30

Bon, je suis en train de patcher le patcher, mais j'ai une question : à quoi sert ce code, qui s'occupe des romcalls ? // handle F-LINE ROM_CALLs if (fline_ROM_CALLs && !strncmp(buffer,"\tjsr _ROM_CALL_",15) && strlen(buffer)<=18) { memmove(buffer+3,buffer+1,strlen(buffer)); // replace "jsr _ROM_CALL_" strncpy(buffer+1,".word _F_LINE+0x",16); // with ".word _F_LINE+0x" } else { // add :l to ROM_CALLs char *p4=strstr(buffer,"_ROM_CALL_"); while (p4) { char *p5=p4; p4+=10; while (isalnum(*p4)||*p4=='_'||*p4=='+'||*p4=='-'||*p4=='*'||*p4=='/') p4++; while (*p4==':'||isalpha(*p4)) memmove(p4,p4+1,strlen(p4)); // zap :w if it's there if (strlen(buffer)>32769) break; // avoid buffer overflow memmove(p4+2,p4,strlen(p4)+1); *(p4++)=':'; // add ":l" *(p4++)='l'; if (!strncmp(p4,"(%pc)",5)||!strncmp(p4,"(%Pc)",5)||!strncmp(p4,"(%pC)",5)||!strncmp(p4,"(%PC)",5)) { memmove(p4,p4+5,strlen(p4+5)+1); } else if ((!strncmp(p4,",%pc)",5)||!strncmp(p4,",%Pc)",5)||!strncmp(p4,",%pC)",5) ||!strncmp(p4,",%PC)",5)) &&(p5>buffer)&&(p5[-1]=='(')) { memmove(p4,p4+5,strlen(p4+5)+1); memmove(p5-1,p5,strlen(p5)+1); } p4=strstr(p4,"_ROM_CALL_"); } p4=strstr(buffer,"__ld_calc_const_"); while (p4) { char *p5=p4; p4+=16; while ((*p4>='0'&&*p4<='9')||(*p4>='a'&&*p4<='z')||(*p4>='A'&&*p4<='Z')||(*p4=='_')||(*p4==':')) p4++; if (!strncmp(p4,"(%pc)",5)||!strncmp(p4,"(%Pc)",5)||!strncmp(p4,"(%pC)",5)||!strncmp(p4,"(%PC)",5)) { memmove(p4,p4+5,strlen(p4+5)+1); } else if ((!strncmp(p4,",%pc)",5)||!strncmp(p4,",%Pc)",5)||!strncmp(p4,",%pC)",5) ||!strncmp(p4,",%PC)",5)) &&(p5>buffer)&&(p5[-1]=='(')) { memmove(p4,p4+5,strlen(p4+5)+1); memmove(p5-1,p5,strlen(p5)+1); } p4=strstr(p4,"__ld_calc_const_"); } }Le if, ok, c'est le remplacement du relogement par un appel F-line.
Juste une incompréhension : pourquoi strlen(buffer)<=18 ?

Par contre, le else...

A quoi sert cette ligne ? while (isalnum(*p4)||*p4=='_'||*p4=='+'||*p4=='-'||*p4=='*'||*p4=='/') p4++;
Ou plutôt, dans quel cas on peut tomber sur un tel code ? isalnum() ok, mais les signes ??

while (*p4==':'||isalpha(*p4)) memmove(p4,p4+1,strlen(p4)); // zap :w if it's there
Là, il vaut mieux ne pas avoir trifouillé dans le .s à la main, parce que question algo c'est pas clean cheeky

Ensuite, par quel miracle pourrait-on avoir un romcall pc-relatif, avec offset ou non d'ailleurs ?

Enfin, que vient faire __ld_calc_const ?

Merci bien. smile

ps -> question d'ordre général : pourquoi des strncmp/strncpy plutôt que leur version sans 'n' ?

31

Bon, un petit patchounet comme ça, ça irait ? tromb Fichier joint : patcher.diff
Et j'ai mis ça dans default.h :#ifdef USE_FLINE_RAM_CALL asm(".set _F_LINE_RAM_CALL,0xF000"); #endif

32

Folco (./30) :
Juste une incompréhension : pourquoi strlen(buffer)<=18 ?
Parce que les numéros de ROM_CALL ont au maximum 3 chiffres hexa.
A quoi sert cette ligne ? while (isalnum(*p4)||*p4=='_'||*p4=='+'||*p4=='-'||*p4=='*'||*p4=='/') p4++;Ou plutôt, dans quel cas on peut tomber sur un tel code ? isalnum() ok, mais les signes ??
Par exemple, la définition de vcbprintf référence _ROM_CALL_53+32 (_ROM_CALL_53 étant sprintf). (À voir si GCC génère effectivement ce code, mais il pourrait en tout cas.)
while (*p4==':'||isalpha(*p4)) memmove(p4,p4+1,strlen(p4)); // zap :w if it's there
Là, il vaut mieux ne pas avoir trifouillé dans le .s à la main, parce que question algo c'est pas clean cheeky
Ça enlève tous les ':' et toutes les lettres, c'est clair que c'est un peu pourri. L'algorithme vient de Sebastian si je me rappelle bien.
Ensuite, par quel miracle pourrait-on avoir un romcall pc-relatif, avec offset ou non d'ailleurs ?
-mpcrel
Enfin, que vient faire __ld_calc_const ?
__ld_calc_const_… est essentiellement un _RAM_CALL en temps de linking. Ça permet d'avoir des binaires optimisés par modèle de calculatrice sans compiler 2 ou 3 fois. Le désavantage est que c'est évidemment incompatible on-calc et que l'optimisation n'est pas aussi bonne que si on compile plusieurs fois (parce que le linker ne peut pas faire de constant folding ni supprimer des branches de if qui ne conviennent pas). Bref, personnellement, je ne conseille pas d'utiliser ça.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

33

Folco (./31) :
Bon, un petit patchounet comme ça, ça irait ? tromb Fichier joint : patcher.diff
Tes opérations sur la chaîne de caractères ne sont pas bonnes, ton strncpy écrase ta chaîne déplacée avec memmove.
Et j'ai mis ça dans default.h :#ifdef USE_FLINE_RAM_CALL
Il manque le S pour être cohérent.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

34

yep, j'ai déjà rectifié tout ça, mais merci.

35

	.file	"main.c"
#NO_APP
	.text
tigcc_compiled.:
	.text
#APP
	.xdef _ti89
	.text
	.xdef _ti89ti
	.text
	.xdef _ti92plus
	.text
	.xdef _v200
	.text
	.set _F_LINE_RAM_CALL,0xF000
	.text
	.set _A_LINE,0xA000
	.text
	.xdef _flag_2
#NO_APP
	.text
	.even
	.globl	_main
_main:
	link.w %fp,#-152
	movm.l #0x1034,-(%sp)
#APP
	bra .
#NO_APP
	lea (-150,%fp),%a4
	cmp.w #21071,50.w
	jbeq .L14
.L2:
	pea StrErrorOS
	jsr _ROM_CALL_E6:l
	moveq #1,%d0
	addq.l #4,%sp
	jbra .L5
.L14:
	cmp.w #130,48.w
	jble .L2
	pea -78(%fp)
	jsr _ROM_CALL_266:l
	move.w %d0,%d3
	addq.l #4,%sp
	jbne .L6
	move.l %a4,%a3
	move.l #262145,-(%sp)
	pea StrPdtlib
	lea PdtlibOffsets,%a2
	lea PdtlibFunctions,%a1
	moveq #1,%d1
	lea StrPdtlib,%a0
	.word _F_LINE_RAM_CALL+0x1D
	move.l %a0,8(%a3)
	move.l %a4,%a3
	addq.l #8,%sp
	tst.l 8(%a4)
	jbeq .L15
	move.l 64(%a4),%a5
	lea LibcOffsets,%a2
	lea LibcFunctions,%a1
	moveq #1,%d1
	lea StrLibc,%a0
	jbsr (%a5)
	move.l %a0,12(%a3)
	tst.l 12(%a4)
	jbne .L10
	move.l 8(%a4),%a0
	.word _F_LINE_RAM_CALL+0x1A
	moveq #3,%d0
	jbra .L5
.L15:
	moveq #2,%d0
	jbra .L5
.L10:
	move.w #1,2(%a4)
	lea (2,%a4),%a1
	move.l %a1,4(%a4)
	clr.l 124(%a4)
	move.l 44(%a4),%a2
	move.l 10(%fp),%a1
	move.w 8(%fp),%d0
	lea (128,%a4),%a0
	jbsr (%a2)
	jbsr CLIFirstPass
.L6:
	move.l 8(%a4),%a0
	.word _F_LINE_RAM_CALL+0x1A
	move.l 12(%a4),%a0
	.word _F_LINE_RAM_CALL+0x1A
	move.w %d3,%d0
.L5:
	movm.l -168(%fp),#0x2c08
	unlk %fp
	rts
#14#

Bon, j'ai toujours un "Unknown error" de PedroM au boot, faut que je fasse un test case et que je vosi où ça déconne.

edit -> bon, a priori et comme prévu, le unknown error se trouve entre la chaise et l'écran.

36

Awwww, un problème de clavier ? tsss

37

grin

38

Faut activer aussi USE_FLINE_ROM_CALLS. smile
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

39

Yep, c'est fait merci. J'ai recompilé depuis une copie fraiche de git, et ça fonctionne nickel. Faut voir ce qu'il reste à faire pour -mpcrel.

(en fait, il n'y avait pas USE_FLINE_ROM_CALLS à cause d'un copier/coller foireux sous emacs, pi j'ai été embêté aussi parce que cet imbécile de patcher avait oublié de s'auto-recompiler avant d'auto-remplacer le patcher d'origine dans /usr/local/share. J'ai fait très fort aujourd'hui trioui)

40

Bon, voici la doc de LibsExec :
35-kernel::LibsExec(char *lib_name, WORD function, BYTE version, ...)	(Preos only)

	The parameters are pushed on the stack.
	It calls the function without modifying the registers, and it pops its argument 
	during the call (LIB_DESCRIPTOR, function, and version).
	BYTE doesn't follow the C convesion for char (Sorry). Uses macro instead.

	It relocs the library, calls the function and unreallocs the library.
	The parameters pushed on the stack are corrupted.
	If there is an error, the parameter 'lib_name' equals zero after the call.
On fait comment pour exprimer la dernière phrase en C, si tant est que ce soit possible ? cheeky

41

lib_name= null_ptr ? Sauf erreur ça doit mettre à 0 le pointeur sur la pile ?
(Pour tester s'il y a eu une erreur au retour en C, contre, je ne sais pas trop grin)

42

Du point de vue de LibsExec, oui, mais du point de vue du programme qui appelle LibsExec ? Il faut lire (sp).l en fait.

43

Peut-être un truc du genre de :

kernel::libsExec("huhu", ...) ;

bool error ;
{
   char* dummy ;
   error= dummy == null_ptr ;
}
if ( error ) {
   throw up ;
}

?

44

Bien vu, mais c'est gore, et sûrement pas garanti grin

45

Oh oui ça l'est (gore grin), mais je doute que tu puisses faire beaucoup mieux en C vu la consigne (sinon un asm{} ?)
À la rigueur tu peux faire une macro ou une fonction wrapper, ça évitera que quelqu'un intercale du code entre l'appel et la lecture de la pile cheeky

46

D'ailleurs il faut déclarer le bool avant, sinon SP ne pointe pas où il faut trinon (enfin, quoi que... pas sûr de comment est gérée la portée une fois compilé en asm, la seconde version est sans doute plus sûre)
bool error ;
kernel::libsExec("huhu", ...) ;
{
   char* dummy ;
   error= dummy == null_ptr ;
}
if ( error ) {
   throw up ;
}

47

Ce n'est pas conforme à la convention d'appel C, tu ne peux pas utiliser ça sans un wrapper (ce qui est problématique à cause des varargs) ou un bidouillage au patcher.

Tu peux par exemple rajouter quelque chose comme:
 tst.l (%sp)
 bne.s 0f
 .word _A_LINE+850  | ER_PRGM_NOT_FOUND
0:
dans le patcher (ce qui permet d'utiliser TRY).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

48

Commande call : PpHd appelé(e) sur ce topic

A moins que tu nous fasses une splendide interface pour le C ? cheeky

(Merci quand même, Kevin hehe)

49

Comme a dit Kevin, cette fonction n'est pas faite pour le C. J'ai pas mieux que la solution de Kevin (ou au lieu de faire un throw, stocker la valeur dans une variable globale).

50

Bah, tu pourrais proposer un kernel::LibsExecThrow (mais tu risques de devoir copier-coller presque toute la fonction).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

51

Moué... Et si la fonction appelée est censé lever une exception en cas de problème ?

52

Le errCode permet de distinguer, sauf si le code d'erreur a le malheur de correspondre.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

53

Bref, ça reste compliqué de toute façon. J'ai fait autrement, je m'en passe. smile
Merci pour tout. smile

54

yop,

Mes soucis sont maintenant réglés avec les ramcalls en tant que fonction.
Par contre, quand je fais ça :
const char* GetSystemDir(void)
{
    return kernel_SystemDir;
}
Le code généré est celui-ci :
GetSystemDir:
        lea _RAM_CALL_2F,%a0
        rts
Ce qui est parfaitement juste en soi, mais comment le patcher ? Détecter le lea et le virer ? C'est pas un peu bourrin quand même ? grin

55

Bah, je ferais l'inverse (garder la variable comme interface et utiliser un #define pour en faire un appel de fonction si USE_FLINE_RAM_CALLS), cf. ./25.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

56

Ah ben oui c'est vrai, merci bien. smile

57

Est-ce que tigcc4ti comprend __attribute__ ((noreturn)) ?

58

Oui. (Enfin, je peux te dire que TIGCC le comprend, pas si GCC4TI l'a cassé ou non. wink)
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

59

Ok, merci. smile

60

Mais putaing gcc :/
Comment faire pour compiler ça : short result; do { result = PARSE_CMDLINE(&CMDLINE, g, FirstPassSwitches, DummyCallback, SwitchFlags, SwitchHelp, SwitchVersion, SwitchSwap, SwitchConfig, SwitchTrace, SwitchVerbose); if (result == PDTLIB_EMPTY_SWITCH) { FPRINTF(STDERR, "blabla1\n"); longjmp(SETJMP_BUF, ERROR_EMPTY_SWITCH); } #ifndef NDEBUG if ((result == PDTLIB_PARSING_STOPPED) || (result == PDTLIB_WRONG_RETURN_VALUE)) { FPRINTF(STDERR, "blabla2\n", GET_CURRENT_ARG(&CMDLINE)); longjmp(SETJMP_BUF, ERROR_WRONG_RETURN_VALUE); } #endif // NDEBUG } while (result != PDTLIB_END_OF_PARSING);en ça :
CLIFirstPass:
.L13:
        pea SwitchVerbose
        pea SwitchTrace
        pea SwitchConfig
        pea SwitchSwap
        pea SwitchVersion
        pea SwitchHelp
        pea SwitchFlags
        pea DummyCallback
        pea FirstPassSwitches
        move.l %a4,-(%sp)
        pea 146(%a4)
        move.l 54(%a4),%a0
        jbsr (%a0)
        lea (44,%sp),%sp
        cmp.w #3,%d0
        jbne .L4
        jbra .L16
.L15:
        pea SwitchVerbose
        pea SwitchTrace
        pea SwitchConfig
        pea SwitchSwap
        pea SwitchVersion
        pea SwitchHelp
        pea SwitchFlags
        pea DummyCallback
        pea FirstPassSwitches
        move.l %a4,-(%sp)
        pea 146(%a4)
        move.l 54(%a4),%a0
        jbsr (%a0)
        lea (44,%sp),%sp
        cmp.w #3,%d0
        jbne .L4
.L16:
        pea .LC0
        move.l 78(%a4),-(%sp)
        move.l 82(%a4),%a0
        jbsr (%a0)
        move.w #7,-(%sp)
        pea 90(%a4)
        .word _F_LINE+0x267
        lea (14,%sp),%sp
        jbra .L13
.L4:
        tst.w %d0
        jbne .L15
        rts
        .section        .data.FirstPassSwitches,"d"
FirstPassSwitches:
        .ascii "fflags\0hhelp\0Vversion\0\0swap\0gconfig\0ttrace\0vverbose\0\0\0"
C'est dingue quand même fou
Au passage, il se peut qu'il y ait deux relocs absolus là-dedans, si ça vous saute aux yeux faites-moi signe, perso j'en vois pas (si le linker fait bien son boulot évidemment)