1

J'ai remarqué une chose qui m'aura donné du mal à être débbugué triso

l'instruction suivante devrait donner :

unsigned long a;
unsigned char *p;

a |= (*p)<<8;

si a = 0 et *p = 1 -> a = 0 | 256 = 256

Une fois compilé celà me retourne des valeurs astronomiques, et en cherchant un peu,
je pense avoir compris que c'était que TIGCC utilisait un registre Ax pour la variable 'a' au lieu d'un registre Dx,
et que du fait de la particularité des registre Ax la lecture des datas était complété par des bits de poids fort à 1,
ce qui explique les valeurs astronomiques de la variable a.

Alors j'ai dû bidouiller la chose suivante :

a |= ((*p)<<8)&0xFF00;

Sur d'autres compilateurs d'autres plateformes 68k, il n'y a pas cet effet.

Quelqu'un a déjà eu le cas?

2

Je serais extrêmement surpris que GCC mette 'a' dans un des registres d'adresse du m68k, parce que l'instruction
or <ea>,an
n'existe pas, et que son allocateur de registre le sait forcément.


As-tu explicitement initialisé 'a' à 0 ? Une absence d'initialisation expliquerait les valeurs bizarres que tu vois. Une initialisation à zéro n'est pas automatique si cette variable est définie dans la portée d'une fonction.
Mais normalement, le compilo devrait te mettre un warning en cas d'utilisation d'une variable non initialisée... à moins que tu aies mis un niveau trop bas de warnings (-Wall -W -Wwrite-strings est le grand minimum pour éliminer les plus grosses bêtises) ?
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

3

Les commutateurs de compilation sont d'origine smile
Mais tu as raison, TIGCC n'utilise pas Ax

Je crois que je commence à comprendre, j'ai regardé le code ASM correspondant généré :

en C :

a = 0x10000|*p++;
a |= (*p++)<<8;

compilé :

moveq #1,%d3
swap %d3
or.b (%a1)+,%d3
.loc 3 117 0
clr.w %d0
move.b (%a1)+,%d0
lsl.w #8,%d0
ext.l %d0
or.l %d0,%d3

En fait, TIGCC met à zero d0 que sur W, alors qu'il devrait le faire sur L

et en spécifiant :

a |= (unsigned long) (*p++)<<8; -> ca marche !

4

Ben logique ^^ Tu devais avoir un warning, non, vu qu'il te manquait un cast ? cheeky Pôbien. (Puis fais-moi confiance, quand je parle de C, je m'y connais. Grave. trifaq).

lsl.w #8,%d0
ext.l %d0
or.l %d0,%d3 

Et puis t'as d'la moule au passage, t'aurais jamais vu le problème avec un nombre <127 grin

5

A part
move.b <ea>,-(sp)
move.w (sp)+,dn1 | registre temporaire
clr.b dn1
or.w dn1,dn2 | dn2 contient les 32 bits de 'a'

(trioui)

peut-être que
a |= (((unsigned short)*p++) << 8);
donnerait du meilleur code: vu qu'on ne touche qu'aux 16 LSB, il est inutile de faire une extension à 32 bits.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

6

Rah Lionel c'et beau ça ton code asm trilove

Mais pourquoi tu dis qu'on touche qu'au 16LSB ? gcc fait un or.l à la fin

7

GCC fait un or.l parce qu'il y a promotion explicite (ou implicite) à 32 bits. Mais comme shifter de 8 rangs à gauche un entier 8 bits donne un entier 16 bits, et comme on sait qu'on va faire un "or", on peut faire un or.w plutôt qu'un "or.l".

Je vois que dans
a = 0x10000|*p++;
a |= (*p++)<<8;

la promotion implicite est signée (il y a un ext.l), et donne du code qui n'est manifestement pas ce que stfox veut...
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

8

euh ... si ton nombre de base est négatif, ton bit #15 sera étendu après la rotation, tu vas pas te retrouver avec un résultat identique pour ton or.
A moins que justement, c'est de cette extension-là qu'on ne veut pas ?
Parce que ça, c'est quand même bien u or de deux pointeurs : a |= (*p)<<8;

9

A moins que justement, c'est de cette extension-là qu'on ne veut pas ?

oui, je pense.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

10

Nickel, merci ! Bravo Lionel smile

11

Ah ok, c'est son code C qui était buggué en fait. sick chsui à la ramasse triso