On nous dit souvent que le matériel ne tient pas compte de la langue dans laquelle un programme est écrit, car il ne voit que le code binaire compilé, mais ce n'est pas toute la vérité. Par exemple, considérons l'humble Z80; ses extensions du jeu d'instructions 8080 incluent des instructions telles que CPIR, ce qui est utile pour balayer des chaînes de style C (terminées par NULL), par exemple pour les effectuer strlen()
. Les concepteurs doivent avoir identifié le fait que l'exécution de programmes en C (par opposition à Pascal, où la longueur d'une chaîne de caractères est dans l'en-tête) était susceptible de servir à leur conception. Un autre exemple classique est la machine Lisp .
Quels autres exemples y a-t-il? Par exemple, les instructions, le nombre et le type de registres , les modes d'adressage, qui permettent à un processeur particulier de préférer les conventions d'un langage particulier? Je suis particulièrement intéressé par les révisions de la même famille.
sizeof(int)
égal à 1 doit obliger ce type àchar
être signé (car ilint
doit pouvoir contenir toutes les valeurs de typechar
). J'ai écrit du code pour une machine oùchar
etint
sont tous deux des entiers signés 16 bits; Les plus grandes difficultés sont qu’il est impossible d’utiliser des unions pour la conversion de types et que, pour stocker efficacement un grand nombre d’octets, il est nécessaire d’emballer et de décompresser manuellement. Ces problèmes sont mineurs comparés à la possibilité en C que sizeof (int) == sizeof (long), depuis ...unsigned int
valeurs. C99 a amélioré cette situation, mais avant C99, il n'existait aucune méthode sécurisée en une étape pour comparer une valeur potentiellement négative à une valeur de typeunsigned int
(il faudrait vérifier si le nombre était négatif avant de faire la comparaison).Réponses:
Les réponses existantes se concentrent sur les modifications d' ISA . Il y a aussi d'autres modifications matérielles. Par exemple, C ++ utilise couramment vtables pour les appels virtuels. À partir du Pentium M , Intel intègre un composant "prédicteur de branche indirecte" qui accélère les appels de fonctions virtuelles.
la source
Le jeu d’instructions Intel 8086 inclut une variante de "ret" qui ajoute une valeur au pointeur de pile après l’ ajout de l’adresse de retour. Ceci est utile pour de nombreuses implémentations Pascal où l'appelant d'une fonction va placer des arguments sur la pile avant de faire un appel de fonction et les extraire ensuite. Si une routine accepte, par exemple, une valeur de quatre octets de paramètres, elle pourrait se terminer par "RET 0004" pour nettoyer la pile. En l'absence d'une telle instruction, une telle convention d'appel aurait probablement obligé le code à afficher l'adresse de retour dans un registre, à mettre à jour le pointeur de pile, puis à accéder à ce registre.
Il est intéressant de noter que la plupart des codes (y compris les routines de système d'exploitation) du Macintosh d'origine ont utilisé la convention d'appel Pascal malgré l'absence d'instruction de facilitation dans le 68000. L'utilisation de cette convention d'appel a permis d'économiser 2 à 4 octets de code sur un site 4-6 octets de code sur le site de retour de chaque fonction prenant des paramètres.
la source
ENTER
contrepartie à cetteRET n
...ENTER
existait dans l'original 8086; il est venu avec les processeurs ultérieurs. Cela soulève toutefois un point intéressant: les modes d’adressage basés sur le tiers sont clairement conçus en fonction de l’utilisation de paramètres empilés et de paramètres locaux empilés via un pointeur de trame. Je trouve cette convention intéressante à plusieurs égards, en particulier si l’on considère que (1) le code en langage assembleur pur est plus apte à utiliser les valeurs dans les registres que la pile, mais (2) les avantages de l’adressage [BP + nn] par rapport à [SP + nn] les adresses sont plus importantes pour les programmes en langage assembleur qui accèdent à des éléments de la pile que ...Un exemple est MIPS, qui a les deux
add
etaddu
pour piéger et ignorer les débordements, respectivement. (Aussisub
etsubu
.) Il avait besoin du premier type d’instruction pour les langues comme Ada (je pense que je n’ai jamais utilisé Ada), qui traitent explicitement des débordements et du second type pour les langues comme C qui les ignorent.Si je me souviens bien, le processeur réel dispose de circuits supplémentaires dans l'ALU pour suivre les débordements. Si le seul langage qui importait était le C, il n'aurait pas besoin de ça.
la source
nmemb*size+offset
octets et que vous devez vous assurer que vous n'obtenez pas un dépassement de capacité.addu
etsubu
(celles qui ne vérifient pas les débordements) sont celles qui ont été ajoutées pour rendre C heureux. Bien sûr, je ne sais pas vraiment - nous l’avons seulement couvert de manière vague et je ne suis certainement pas un expert en architecture: P.La série Burroughs 5000 a été conçue pour prendre en charge efficacement ALGOL et le processeur Intel iAPX-432 a été conçu pour exécuter efficacement Ada. Le transputeur Inmos avait son propre langage, Occam. Je pense que le processeur "Propeller" de Parallax a été conçu pour être programmé à l'aide de sa propre variante de BASIC.
Ce n'est pas un langage, mais le jeu d'instructions VAX-11 contient une seule instruction pour charger un contexte de processus, qui a été conçu à la suite d'une demande de l'équipe de conception de VMS. Je ne me souviens pas des détails, mais ISTR nécessitait tellement d'instructions à mettre en œuvre que cela limitait sérieusement le nombre de processus pouvant être planifiés.
la source
Une chose que personne ne semble avoir mentionnée jusqu’à présent est que les progrès en matière d’optimisation du compilateur (où le langage de base est en grande partie hors de propos) ont entraîné le passage des jeux d’instructions CISC (qui étaient en grande partie conçus pour être codés par des humains) aux jeux d’instructions RISC (qui étaient largement conçu pour être codé par les compilateurs.)
la source
La famille Motorola 68000 a introduit un mode d’ adresse automatique qui rend la copie de données via le processeur très efficace et compacte.
[Exemple mis à jour]
c'était un code c ++ qui a influencé l'assembleur 68000
implémenté en assembleur classique (pseudocode, j'ai oublié les commandes de l'assembleur 68000)
avec la nouvelle adresse, il est devenu quelque chose de similaire à
seulement deux instructions par boucle au lieu de 4.
la source
Le mainframe de la série Z d’IBM est le descendant de l’IBM 360 des années 1960.
Plusieurs instructions ont été mises en place pour accélérer les programmes COBOL et Fortran. L'exemple classique étant le
BXLE
- "Branch on Index Low Or Equal", qui est la plupart du temps unefor
boucle Fortran ou un COBOLPERFORM VARYING x from 1 by 1 until x > n
encapsulé dans une seule instruction.Il existe également toute une famille d'instructions décimales condensées destinées à prendre en charge l'arithmétique décimale à virgule fixe commune aux programmes COBOL.
la source
DO
boucle FORTRAN .Les premiers processeurs Intel présentaient les fonctionnalités suivantes, dont beaucoup sont désormais obsolètes en mode 64 bits:
L’indicateur de signature, situé dans le registre d’état de nombreuses CPU, permet de réaliser facilement des opérations arithmétiques signées ET non signées.
Le jeu d'instructions SSE 4.1 introduit des instructions pour le traitement des chaînes, comptées et terminées à zéro (PCMPESTR, etc.)
De plus, j'imagine qu'un certain nombre de fonctionnalités au niveau du système ont été conçues pour assurer la sécurité du code compilé (vérification de la limite de segment, portes d'appel avec copie de paramètres, etc.).
la source
Certains processeurs ARM, principalement ceux des périphériques mobiles, incluent (d) l’extension Jazelle, qui est un interpréteur JVM matériel; il interprète directement le bytecode Java. La JVM compatible Jazelle peut utiliser le matériel pour accélérer l'exécution et éliminer une grande partie de la JIT, mais le repli sur la VM logicielle est toujours garanti si le bytecode ne peut pas être interprété sur une puce.
Les processeurs avec cette unité incluent l'instruction BXJ, qui place le processeur en mode "Jazelle" spécial, ou si l'activation de l'unité a échoué, elle est simplement interprétée comme une instruction de branche normale. L'unité réutilise les registres ARM pour maintenir l'état de la JVM.
ThumbEE est le successeur de la technologie Jazelle
la source
Autant que je sache, c'était plus courant dans le passé.
Lors d’ une séance de questions au cours de laquelle James Gosling a déclaré qu’il existait des personnes qui essayaient de créer du matériel pouvant mieux gérer le bytecode de la machine virtuelle Java, mais qu’elles trouveraient alors un moyen de le faire avec des informations "génériques" communes x86 (peut-être en compilant le fichier). bytecode de manière intelligente).
Il a mentionné qu’il était avantageux d’utiliser la puce populaire générique (telle que celle d’Intel), car une grande société consacre d’énormes sommes d’argent au produit.
La vidéo vaut le détour. Il en parle à la minute 19 ou 20.
la source
J'ai fait une recherche rapide de page et il semble que personne n'ait mentionné les processeurs développés spécifiquement pour exécuter Forth . Le langage de programmation Forth est basé sur une pile, compact et utilisé dans les systèmes de contrôle.
la source
Le processeur Intel iAPX a été spécialement conçu pour les langues OO. N'a pas tout à fait travaillé, cependant.
la source
MOVEM du 68000 était ce qui convenait le mieux pour placer plusieurs registres sur la pile en une seule instruction, ce à quoi de nombreuses langues s'attendaient.
Si vous avez vu MOVEM (MOVE Multiple) précéder JSR (Jump SubRoutine) tout au long du code, vous saviez généralement que vous utilisiez du code C conforme.
MOVEM autorisait l'incrémentation automatique du registre de destination, permettant à chaque utilisateur de continuer l'empilement sur la destination ou la suppression de la pile en cas de décrémentation automatique.
http://68k.hax.com/MOVEM
la source
L'architecture AVR d'Atmel est entièrement conçue dès le départ pour être adaptée à la programmation en langage C. Par exemple, cette note d'application développe davantage.
OMI ceci est étroitement lié à l’excellente réponse de rockets4kids , avec les premiers PIC16-s en cours de développement pour la programmation directe par assembleur (40 instructions au total), les familles ultérieures ciblant C.
la source
Lors de la conception du coprocesseur numérique 8087, il était assez courant que les langages effectuent toutes les calculs en virgule flottante en utilisant le type de précision le plus élevé, et arrondissaient le résultat à une précision inférieure lors de l'affectation à une variable de moindre précision. Dans la norme C d'origine, par exemple, la séquence:
favoriserait
a
etb
àdouble
, les ajouter, promouvoirc
àdouble
, ajouter, puis stocker le résultat arrondi àfloat
. Même s’il aurait souvent été plus rapide pour un compilateur de générer du code permettant d’exécuter des opérations directement sur le typefloat
, il était plus simple de disposer d’un ensemble de routines à virgule flottante qui ne fonctionneraient que sur le typedouble
, ainsi que de routines à convertir en /. à partir defloat
, que d'avoir des ensembles distincts de routines pour gérer les opérations surfloat
etdouble
. Le 8087 a été conçu autour de cette approche de l'arithmétique, effectuant toutes les opérations arithmétiques en utilisant un type à virgule flottante de 80 bits [80 bits a probablement été choisi pour les raisons suivantes:Sur de nombreux processeurs 16 et 32 bits, il est plus rapide de travailler avec une mantisse 64 bits et un exposant séparé que de travailler avec une valeur qui divise un octet entre la mantisse et l'exposant.
Il est très difficile d'effectuer des calculs qui soient précis à la précision des types numériques utilisés. si vous essayez par exemple de calculer quelque chose comme log10 (x), il est plus facile et plus rapide de calculer un résultat précis à moins de 100 ul d'un type 80 bits que de calculer un résultat précis à moins de 1ulp d'un 64 bits Si vous arrondissez le premier résultat à une précision de 64 bits, vous obtiendrez une valeur de 64 bits plus précise que la dernière.
Malheureusement, les versions futures du langage ont changé la sémantique du fonctionnement des types à virgule flottante; alors que la sémantique 8087 aurait été très utile si les langages les avaient toujours pris en charge, si les fonctions f1 (), f2 (), etc. renvoyaient le type
float
, de nombreux auteurs de compilateurs se chargeraient de créerlong double
un alias pour le type double 64 bits plutôt que le type 80 bits du compilateur (et ne fournissent aucun autre moyen de créer des variables 80 bits), et d'évaluer arbitrairement quelque chose comme:de l'une des manières suivantes:
Notez que si f3 et f4 renvoient respectivement les mêmes valeurs que f1 et f2, l'expression d'origine doit clairement renvoyer zéro, mais nombre de ces dernières expressions ne le peuvent pas. Cela a conduit des personnes à condamner la "précision supplémentaire" du 8087 alors même que la dernière formulation serait généralement supérieure à la troisième et que, avec un code utilisant le double type étendu de manière appropriée, il serait rarement inférieur.
Dans les années qui ont suivi, Intel a réagi à la tendance du langage (à mon humble avis) à forcer les résultats intermédiaires à être arrondis à la précision des opérandes en concevant leurs processeurs ultérieurs de manière à favoriser ce comportement, au détriment du code précision sur les calculs intermédiaires.
la source
## How the stack changed the processor
et## How floating point changed the processor
) de manière à ce que les gens puissent avoir la bonne mentalité lorsqu’ils le lisent et soient moins enclins à penser que vous avez été distrait dans votre réponse ou votre nouvelle publication. idem (similaire) réponses.