diff options
author | tma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-11-02 16:05:14 +0000 |
---|---|---|
committer | tma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-11-02 16:05:14 +0000 |
commit | 2e5b78c0a36480e3735692cd2795dee291936fe8 (patch) | |
tree | 0dad62aefa78bb418723d298e6d4181e2bb61a37 /code/tools/lcc/src | |
parent | 74f0ff6259b3cfa4862ea45a9e70db5acf3ab347 (diff) | |
download | ioquake3-aero-2e5b78c0a36480e3735692cd2795dee291936fe8.tar.gz ioquake3-aero-2e5b78c0a36480e3735692cd2795dee291936fe8.zip |
* Removed the last of the binary target stuff from lcc (hopefully)
git-svn-id: svn://svn.icculus.org/quake3/trunk@228 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/tools/lcc/src')
-rw-r--r-- | code/tools/lcc/src/alpha.md | 1192 | ||||
-rw-r--r-- | code/tools/lcc/src/bind.c | 15 | ||||
-rw-r--r-- | code/tools/lcc/src/mips.md | 1120 | ||||
-rw-r--r-- | code/tools/lcc/src/pass2.c | 665 | ||||
-rw-r--r-- | code/tools/lcc/src/sparc.md | 1163 | ||||
-rw-r--r-- | code/tools/lcc/src/x86.md | 998 | ||||
-rw-r--r-- | code/tools/lcc/src/x86linux.md | 1081 |
7 files changed, 0 insertions, 6234 deletions
diff --git a/code/tools/lcc/src/alpha.md b/code/tools/lcc/src/alpha.md deleted file mode 100644 index 450dfd3..0000000 --- a/code/tools/lcc/src/alpha.md +++ /dev/null @@ -1,1192 +0,0 @@ -%{ -#define INTTMP ((0xff<<1)|(1<<22)|(1<<25)|(1<<27)) -#define INTVAR (0x3f<<9) -#define FLTTMP ((0x3f<<10)|(0x1ff<<22)) -#define FLTVAR (0xff<<2) - -#define INTRET 0x00000001 -#define FLTRET 0x00000003 - -#define readsreg(p) \ - (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P) -#define setsrc(d) ((d) && (d)->x.regnode && \ - (d)->x.regnode->set == src->x.regnode->set && \ - (d)->x.regnode->mask&src->x.regnode->mask) - -#define relink(a, b) ((b)->x.prev = (a), (a)->x.next = (b)) - -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -static void address(Symbol, Symbol, long); -static void blkfetch(int, int, int, int); -static void blkloop(int, int, int, int, int, int[]); -static void blkstore(int, int, int, int); -static void defaddress(Symbol); -static void defconst(int, int, Value); -static void defstring(int, char *); -static void defsymbol(Symbol); -static void doarg(Node); -static void emit2(Node); -static void export(Symbol); -static void clobber(Node); -static void function(Symbol, Symbol [], Symbol [], int); -static void global(Symbol); -static void import(Symbol); -static void local(Symbol); -static void progbeg(int, char **); -static void progend(void); -static void segment(int); -static void space(int); -static void target(Node); -static Symbol ireg[32], freg[32]; -static Symbol iregw, fregw; - -static int tmpregs[] = {4, 2, 3}; -static Symbol blkreg; - -static int cseg; - -static char *currentfile; - -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRF4(VREGP) "# read register\n" -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRF8(VREGP) "# read register\n" -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" -con: CNSTI1 "%a" -con: CNSTU1 "%a" - -con: CNSTI2 "%a" -con: CNSTU2 "%a" - -con: CNSTI4 "%a" -con: CNSTU4 "%a" -con: CNSTP4 "%a" - -con: CNSTI8 "%a" -con: CNSTU8 "%a" -con: CNSTP8 "%a" -stmt: reg "" -acon: con "%0" -acon: ADDRGP8 "%a" - -addr: ADDI4(reg,acon) "%1($%0)" -addr: ADDI8(reg,acon) "%1($%0)" -addr: ADDU8(reg,acon) "%1($%0)" -addr: ADDP8(reg,acon) "%1($%0)" - -addr: acon "%0" -addr: reg "($%0)" - -addr: ADDRFP8 "%a+%F($sp)" -addr: ADDRLP8 "%a+%F($sp)" - -reg: addr "lda $%c,%0\n" 1 - -reg: CNSTI1 "# reg\n" range(a, 0, 0) -reg: CNSTI2 "# reg\n" range(a, 0, 0) -reg: CNSTI4 "# reg\n" range(a, 0, 0) -reg: CNSTI8 "# reg\n" range(a, 0, 0) -reg: CNSTU1 "# reg\n" range(a, 0, 0) -reg: CNSTU2 "# reg\n" range(a, 0, 0) -reg: CNSTU4 "# reg\n" range(a, 0, 0) -reg: CNSTU8 "# reg\n" range(a, 0, 0) -reg: CNSTP8 "# reg\n" range(a, 0, 0) - -stmt: ASGNI1(addr,reg) "stb $%1,%0\n" 1 -stmt: ASGNU1(addr,reg) "stb $%1,%0\n" 1 -stmt: ASGNI2(addr,reg) "stw $%1,%0\n" 1 -stmt: ASGNU2(addr,reg) "stw $%1,%0\n" 1 - -stmt: ASGNI4(addr,reg) "stl $%1,%0\n" 1 -stmt: ASGNU4(addr,reg) "stl $%1,%0\n" 1 -stmt: ASGNI8(addr,reg) "stq $%1,%0\n" 1 -stmt: ASGNU8(addr,reg) "stq $%1,%0\n" 1 -stmt: ASGNP8(addr,reg) "stq $%1,%0\n" 1 - -reg: INDIRI1(reg) "ldb $%c,($%0)\n" 1 -reg: INDIRI2(reg) "ldw $%c,($%0)\n" 1 -reg: INDIRI4(addr) "ldl $%c,%0\n" 1 -reg: INDIRI8(addr) "ldq $%c,%0\n" 1 -reg: INDIRP8(addr) "ldq $%c,%0\n" 1 -reg: INDIRU1(reg) "ldbu $%c,($%0)\n" 1 -reg: INDIRU2(reg) "ldwu $%c,($%0)\n" 1 -reg: INDIRU4(addr) "ldl $%c,%0\nzap $%c,240,$%c\n" 2 -reg: INDIRU8(addr) "ldq $%c,%0\n" 1 - -reg: CVII4(INDIRI1(reg)) "ldb $%c,($%0)\n" 1 -reg: CVII8(INDIRI1(reg)) "ldb $%c,($%0)\n" 1 -reg: CVII4(INDIRI2(reg)) "ldw $%c,($%0)\n" 1 -reg: CVII8(INDIRI2(reg)) "ldw $%c,($%0)\n" 1 -reg: CVII8(INDIRI4(addr)) "ldl $%c,%0\n" 1 - -reg: CVUU4(INDIRU1(reg)) "ldbu $%c,($%0)\n" 1 -reg: CVUU8(INDIRU1(reg)) "ldbu $%c,($%0)\n" 1 -reg: CVUU4(INDIRU2(reg)) "ldwu $%c,($%0)\n" 1 -reg: CVUU8(INDIRU2(reg)) "ldwu $%c,($%0)\n" 1 -reg: CVUU8(INDIRU4(addr)) "ldl $%c,%0\nzap $%c,240,$%c\n" 2 - -reg: CVUI4(INDIRU1(reg)) "ldbu $%c,($%0)\n" 1 -reg: CVUI8(INDIRU1(reg)) "ldbu $%c,($%0)\n" 1 -reg: CVUI4(INDIRU2(reg)) "ldwu $%c,($%0)\n" 1 -reg: CVUI8(INDIRU2(reg)) "ldwu $%c,($%0)\n" 1 -reg: CVUI8(INDIRU4(addr)) "ldl $%c,%0\nzap $%c,240,$%c\n" 2 - -reg: CVIU8(reg) "mov $%0,$%c\n" move(a) - -reg: INDIRF4(addr) "lds $f%c,%0\n" 1 -reg: INDIRF8(addr) "ldt $f%c,%0\n" 1 -stmt: ASGNF4(addr,reg) "sts $f%1,%0\n" 1 -stmt: ASGNF8(addr,reg) "stt $f%1,%0\n" 1 - -reg: MULI4(reg,rc) "mull $%0,%1,$%c\n" 1 -reg: MULI8(reg,rc) "mulq $%0,%1,$%c\n" 1 -reg: MULU4(reg,rc) "mull $%0,%1,$%c\nzap $%c,240,$%c\n" 2 -reg: MULU8(reg,rc) "mulq $%0,%1,$%c\n" 1 - -reg: DIVI4(reg,rc) "divl $%0,%1,$%c\n" 1 -reg: DIVI8(reg,rc) "divq $%0,%1,$%c\n" 1 -reg: DIVU4(reg,rc) "divlu $%0,%1,$%c\n" 1 -reg: DIVU8(reg,rc) "divqu $%0,%1,$%c\n" 1 -reg: MODI4(reg,rc) "reml $%0,%1,$%c\n" 1 -reg: MODI8(reg,rc) "remq $%0,%1,$%c\n" 1 -reg: MODU4(reg,rc) "remlu $%0,%1,$%c\n" 1 -reg: MODU8(reg,rc) "remqu $%0,%1,$%c\n" 1 - -rc: con "%0" -rc: reg "$%0" - -reg: ADDI4(reg,rc) "addl $%0,%1,$%c\n" 1 -reg: ADDI8(reg,rc) "addq $%0,%1,$%c\n" 1 -reg: ADDP8(reg,rc) "addq $%0,%1,$%c\n" 1 -reg: ADDU4(reg,rc) "addl $%0,%1,$%c\nzap $%c,240,$%c\n" 2 -reg: ADDU8(reg,rc) "addq $%0,%1,$%c\n" 1 -reg: SUBI4(reg,rc) "subl $%0,%1,$%c\n" 1 -reg: SUBI8(reg,rc) "subq $%0,%1,$%c\n" 1 -reg: SUBP8(reg,rc) "subq $%0,%1,$%c\n" 1 -reg: SUBU4(reg,rc) "subl $%0,%1,$%c\nzap $%c,240,$%c\n" 2 -reg: SUBU8(reg,rc) "subq $%0,%1,$%c\n" 1 - -reg: BANDI4(reg,rc) "and $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: BANDI8(reg,rc) "and $%0,%1,$%c\n" 1 -reg: BANDU4(reg,rc) "and $%0,%1,$%c\n" 1 -reg: BANDU8(reg,rc) "and $%0,%1,$%c\n" 1 -reg: BORI4(reg,rc) "or $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: BORI8(reg,rc) "or $%0,%1,$%c\n" 1 -reg: BORU4(reg,rc) "or $%0,%1,$%c\n" 1 -reg: BORU8(reg,rc) "or $%0,%1,$%c\n" 1 -reg: BXORI4(reg,rc) "xor $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: BXORI8(reg,rc) "xor $%0,%1,$%c\n" 1 -reg: BXORU4(reg,rc) "xor $%0,%1,$%c\n" 1 -reg: BXORU8(reg,rc) "xor $%0,%1,$%c\n" 1 - -rc6: CNSTI4 "%a" range(a,0,63) -rc6: CNSTI8 "%a" range(a,0,63) -rc6: reg "$%0" - -reg: LSHI4(reg,rc6) "sll $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: LSHI8(reg,rc6) "sll $%0,%1,$%c\n" 1 -reg: LSHU4(reg,rc6) "sll $%0,%1,$%c\nzap $%c,240,$%c\n" 2 -reg: LSHU8(reg,rc6) "sll $%0,%1,$%c\n" 1 -reg: RSHI4(reg,rc6) "sra $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: RSHI8(reg,rc6) "sra $%0,%1,$%c\n" 1 -reg: RSHU4(reg,rc6) "srl $%0,%1,$%c\n" 1 -reg: RSHU8(reg,rc6) "srl $%0,%1,$%c\n" 1 - -reg: BCOMI4(reg) "not $%0,$%c\naddl $%c,0,$%c\n" 2 -reg: BCOMU4(reg) "not $%0,$%c\nzap $%c,240,$%c\n" 2 -reg: BCOMI8(reg) "not $%0,$%c\n" 1 -reg: BCOMU8(reg) "not $%0,$%c\n" 1 -reg: NEGI4(reg) "negl $%0,$%c\n" 1 -reg: NEGI8(reg) "negq $%0,$%c\n" 1 -reg: LOADI1(reg) "mov $%0,$%c\n" move(a) -reg: LOADI2(reg) "mov $%0,$%c\n" move(a) -reg: LOADI4(reg) "mov $%0,$%c\n" move(a) -reg: LOADI8(reg) "mov $%0,$%c\n" move(a) -reg: LOADP8(reg) "mov $%0,$%c\n" move(a) -reg: LOADU1(reg) "mov $%0,$%c\n" move(a) -reg: LOADU2(reg) "mov $%0,$%c\n" move(a) -reg: LOADU4(reg) "mov $%0,$%c\n" move(a) -reg: LOADU8(reg) "mov $%0,$%c\n" move(a) - -reg: ADDF4(reg,reg) "adds $f%0,$f%1,$f%c\n" 1 -reg: ADDF8(reg,reg) "addt $f%0,$f%1,$f%c\n" 1 -reg: DIVF4(reg,reg) "divs $f%0,$f%1,$f%c\n" 1 -reg: DIVF8(reg,reg) "divt $f%0,$f%1,$f%c\n" 1 -reg: MULF4(reg,reg) "muls $f%0,$f%1,$f%c\n" 1 -reg: MULF8(reg,reg) "mult $f%0,$f%1,$f%c\n" 1 -reg: SUBF4(reg,reg) "subs $f%0,$f%1,$f%c\n" 1 -reg: SUBF8(reg,reg) "subt $f%0,$f%1,$f%c\n" 1 -reg: LOADF4(reg) "fmov $f%0,$f%c\n" move(a) -reg: LOADF8(reg) "fmov $f%0,$f%c\n" move(a) -reg: NEGF4(reg) "negs $f%0,$f%c\n" 1 -reg: NEGF8(reg) "negt $f%0,$f%c\n" 1 -reg: CVII4(reg) "sll $%0,8*(8-%a),$%c\nsra $%c,8*(8-%a),$%c\n" 2 -reg: CVII8(reg) "sll $%0,8*(8-%a),$%c\nsra $%c,8*(8-%a),$%c\n" 2 -reg: CVUI4(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 -reg: CVUI8(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 -reg: CVUU4(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 -reg: CVUU8(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 - -reg: CVUP8(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 - -reg: CVFF4(reg) "cvtts $f%0,$f%c\n" 1 -reg: CVFF8(reg) "cvtst $f%0,$f%c\n" 1 - -reg: CVIF4(reg) "stq $%0,-56+%F($sp)\nldt $%f%c,-56+%F($sp)\ncvtqs $f%c,$f%c\n" 3 -reg: CVIF8(reg) "stq $%0,-56+%F($sp)\nldt $%f%c,-56+%F($sp)\ncvtqt $f%c,$f%c\n" 3 -reg: CVIF4(INDIRI4(addr)) "lds $f%c,%0\ncvtlq $f%c,$f%c\ncvtqs $f%c,$f%c\n" 3 -reg: CVIF4(INDIRI8(addr)) "ldt $f%c,%0\ncvtqs $f%c,$f%c\n" 2 -reg: CVIF8(INDIRI4(addr)) "lds $f%c,%0\ncvtlq $f%c,$f%c\ncvtqt $f%c,$f%c\n" 3 -reg: CVIF8(INDIRI8(addr)) "ldt $f%c,%0\ncvtqt $f%c,$f%c\n" 2 - -reg: CVFI4(reg) "cvttqc $f%0,$f1\ncvtql $f1,$f1\nsts $f1,-56+%F($sp)\nldl $%c,-56+%F($sp)\n" 4 -reg: CVFI8(reg) "cvttqc $f%0,$f1\nstt $f1,-56+%F($sp)\nldq $%c,-56+%F($sp)\n" 3 - -stmt: LABELV "%a:\n" - -stmt: JUMPV(acon) "br %0\n" 1 -stmt: JUMPV(reg) "jmp ($%0)\n" 1 - -stmt: EQI4(reg,rc6) "cmpeq $%0,%1,$23\nbne $23,%a\n" 2 -stmt: EQU4(reg,rc6) "cmpeq $%0,%1,$23\nbne $23,%a\n" 2 -stmt: EQI8(reg,rc6) "cmpeq $%0,%1,$23\nbne $23,%a\n" 2 -stmt: EQU8(reg,rc6) "cmpeq $%0,%1,$23\nbne $23,%a\n" 2 -stmt: NEI4(reg,rc6) "cmpeq $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: NEU4(reg,rc6) "cmpeq $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: NEI8(reg,rc6) "cmpeq $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: NEU8(reg,rc6) "cmpeq $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GEI4(reg,rc6) "cmplt $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GEI8(reg,rc6) "cmplt $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GEU4(reg,rc6) "cmpult $%0,%1,$23\nbeq $23,%a\n" 1 -stmt: GEU8(reg,rc6) "cmpult $%0,%1,$23\nbeq $23,%a\n" 1 -stmt: GTI4(reg,rc6) "cmple $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GTI8(reg,rc6) "cmple $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GTU4(reg,rc6) "cmpule $%0,%1,$23\nbeq $23,%a\n" 1 -stmt: GTU8(reg,rc6) "cmpule $%0,%1,$23\nbeq $23,%a\n" 1 -stmt: LEI4(reg,rc6) "cmple $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LEI8(reg,rc6) "cmple $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LEU4(reg,rc6) "cmpule $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LEU8(reg,rc6) "cmpule $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LTI4(reg,rc6) "cmplt $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LTI8(reg,rc6) "cmplt $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LTU4(reg,rc6) "cmpult $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LTU8(reg,rc6) "cmpult $%0,%1,$23\nbne $23,%a\n" 2 - -stmt: EQF4(reg,reg) "cmpteq $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: EQF8(reg,reg) "cmpteq $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: LEF4(reg,reg) "cmptle $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: LEF8(reg,reg) "cmptle $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: LTF4(reg,reg) "cmptlt $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: LTF8(reg,reg) "cmptlt $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 - -stmt: NEF4(reg,reg) "cmpteq $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: NEF8(reg,reg) "cmpteq $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: GEF4(reg,reg) "cmptlt $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: GEF8(reg,reg) "cmptlt $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: GTF4(reg,reg) "cmptle $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: GTF8(reg,reg) "cmptle $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 - -ar: ADDRGP8 "%a" -ar: reg "($%0)" - -reg: CALLF4(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLF8(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLI4(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLI8(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLP8(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLU4(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLU8(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -stmt: CALLV(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 - -stmt: RETF4(reg) "# ret\n" 1 -stmt: RETF8(reg) "# ret\n" 1 -stmt: RETI4(reg) "# ret\n" 1 -stmt: RETU4(reg) "# ret\n" 1 -stmt: RETI8(reg) "# ret\n" 1 -stmt: RETU8(reg) "# ret\n" 1 -stmt: RETP8(reg) "# ret\n" 1 -stmt: RETV(reg) "# ret\n" 1 - -stmt: ARGF4(reg) "# arg\n" 1 -stmt: ARGF8(reg) "# arg\n" 1 -stmt: ARGI4(reg) "# arg\n" 1 -stmt: ARGI8(reg) "# arg\n" 1 -stmt: ARGP8(reg) "# arg\n" 1 -stmt: ARGU4(reg) "# arg\n" 1 -stmt: ARGU8(reg) "# arg\n" 1 - -stmt: ARGB(INDIRB(reg)) "# argb %0\n" 1 -stmt: ASGNB(reg,INDIRB(reg)) "# asgnb %0 %1\n" 1 - -%% -static void progend(void){} - -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - parseflags(argc, argv); - - for (i = 0; i < 32; i++) - freg[i] = mkreg("%d", i, 1, FREG); - for (i = 0; i < 32; i++) - ireg[i] = mkreg("%d", i, 1, IREG); - ireg[29]->x.name = "gp"; - ireg[30]->x.name = "sp"; - fregw = mkwildcard(freg); - iregw = mkwildcard(ireg); - - tmask[IREG] = INTTMP; tmask[FREG] = FLTTMP; - vmask[IREG] = INTVAR; vmask[FREG] = FLTVAR; - - blkreg = mkreg("1", 1, 0xf, IREG); - -} - -static Symbol rmap(int opk) { - switch (optype(opk)) { - case I: case U: case P: case B: - return iregw; - case F: - return fregw; - default: - return 0; - } -} - -static Symbol argreg(int offset, int ty) { - if (offset >= 48) - return NULL; - else if (ty == F) - return freg[(offset/8) + 16]; - else - return ireg[(offset/8) + 16]; -} - -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case CNST+I: case CNST+U: case CNST+P: - if (range(p, 0, 0) == 0) { - setreg(p, ireg[31]); - p->x.registered = 1; - } - break; - case CNST+F: - if (p->syms[0]->u.c.v.d == 0) { - setreg(p, freg[31]); - p->x.registered = 1; - } - break; - - case CALL+V: - rtarget(p, 0, ireg[27]); - break; - case CALL+F: - rtarget(p, 0, ireg[27]); - setreg(p, freg[0]); - break; - case CALL+I: case CALL+P: case CALL+U: - rtarget(p, 0, ireg[27]); - setreg(p, ireg[0]); - break; - case RET+F: - rtarget(p, 0, freg[0]); - break; - case RET+I: case RET+U: case RET+P: - rtarget(p, 0, ireg[0]); - break; - - case ARG+F: case ARG+I: case ARG+P: case ARG+U: { - Symbol q = argreg(p->syms[2]->u.c.v.i, optype(p->op)); - if (q) - rtarget(p, 0, q); - break; - } - - - case ASGN+B: rtarget(p->kids[1], 0, blkreg); break; - case ARG+B: rtarget(p->kids[0], 0, blkreg); break; - - } -} - -static void clobber(Node p) { - assert(p); - switch (specific(p->op)) { - case ASGN+I: case ASGN+U: - if (opsize(p->op) <= 2) - spill(1<<24, IREG, p); - break; - - case DIV+I: case DIV+U: case MOD+I: case MOD+U: - spill(((1<<27)|(3<<24))&~p->syms[RX]->x.regnode->mask, IREG, p); - break; - - case CALL+F: - spill(INTTMP | INTRET, IREG, p); - spill(FLTTMP, FREG, p); - break; - case CALL+I: case CALL+P: case CALL+U: - spill(INTTMP, IREG, p); - spill(FLTTMP | FLTRET, FREG, p); - break; - case CALL+V: - spill(INTTMP | INTRET, IREG, p); - spill(FLTTMP | FLTRET, FREG, p); - break; - - } -} - -static void emit2(Node p) { - int dst, n, src, sz, ty; - static int ty0; - Symbol q; - - switch (specific(p->op)) { - case ARG+F: case ARG+I: case ARG+P: case ARG+U: - ty = optype(p->op); - sz = opsize(p->op); - q = argreg(p->syms[2]->u.c.v.i, ty); - src = getregnum(p->x.kids[0]); - if (q) - break; - else if (ty == F && sz == 4) - print("sts $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i - 48); - else if (ty == F && sz == 8) - print("stt $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i - 48); - else if (sz == 4) - print("stq $%d,%d($sp)\n", src, p->syms[2]->u.c.v.i - 48); - else if (sz == 8) - print("stq $%d,%d($sp)\n", src, p->syms[2]->u.c.v.i - 48); - else - assert(0); - break; - - case ASGN+B: - dalign = salign = p->syms[1]->u.c.v.i; - blkcopy(getregnum(p->x.kids[0]), 0, - getregnum(p->x.kids[1]), 0, - p->syms[0]->u.c.v.i, tmpregs); - break; - - - case ARG+B: { - int doff = p->syms[2]->u.c.v.i, soff = 0, sreg = getregnum(p->x.kids[0]); - dalign = 8; - salign = p->syms[1]->u.c.v.i; - n = p->syms[0]->u.c.v.i; - for ( ; doff <= 40 && n > 0; doff += 8) { - print("uldq $%d,%d($%d)\n", (doff/8)+16, soff, sreg); - soff += 8; - n -= 8; - } - if (n > 0) - blkcopy(30, doff - 48, sreg, soff, n, tmpregs); - break; - } - - } -} - -static void doarg(Node p) { - p->syms[2] = intconst(mkactual(8, roundup(p->syms[0]->u.c.v.i,8))); -} - -static void local(Symbol p) { - if (askregvar(p, rmap(ttob(p->type))) == 0) - mkauto(p); -} - -static int bitcount(unsigned mask) { - unsigned i, n = 0; - - for (i = 1; i; i <<= 1) - if (mask&i) - n++; - return n; -} - -static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - int i, sizeargs, saved, sizefsave, sizeisave, varargs; - Symbol r, argregs[6]; - - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~(unsigned)0; - maxargoffset = offset = maxoffset = 0; - - for (i = 0; callee[i]; i++) - ; - varargs = variadic(f->type) - || i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0; - if (varargs) - sizeargs = 2*48; - else - sizeargs = 48; - - for (i = 0; callee[i]; i++) { - Symbol p = callee[i]; - Symbol q = caller[i]; - assert(q); - if (isfloat(p->type) && varargs) { - p->x.offset = q->x.offset = offset - 2*48; - p->x.name = q->x.name = stringd(offset - 2*48); - } else { - p->x.offset = q->x.offset = offset - 48; - p->x.name = q->x.name = stringd(offset - 48); - } - offset = roundup(offset, q->type->align); - r = argreg(offset, optype(ttob(q->type))); - if (i < 6) - argregs[i] = r; - offset = roundup(offset + q->type->size, 8); - if (varargs) - p->sclass = AUTO; - else if (r && ncalls == 0 && !isstruct(q->type) && !p->addressed -) { - p->sclass = q->sclass = REGISTER; - askregvar(p, r); - assert(p->x.regnode && p->x.regnode->vbl == p); - q->x = p->x; - q->type = p->type; - } else if (askregvar(p, rmap(ttob(p->type))) - && r != NULL /* - && (isint(p->type) || p->type == q->type) */ -) { - assert(q->sclass != REGISTER); - p->sclass = q->sclass = REGISTER; - q->type = p->type; - } - - } - assert(!caller[i]); - - offset = sizeargs + 8; - gencode(caller, callee); - usedmask[IREG] &= ~(INTTMP|(0x3f<<16)|INTRET); - usedmask[FREG] &= ~(FLTTMP|(0x3f<<16)|FLTRET); - if (ncalls || usedmask[IREG] || usedmask[FREG]) - usedmask[IREG] |= 1<<26; - sizefsave = 8*bitcount(usedmask[FREG]); - sizeisave = 8*bitcount(usedmask[IREG]); - if (maxargoffset > 48) - maxargoffset -= 48; - else - maxargoffset = 0; - if (maxoffset < sizeargs) - maxoffset = sizeargs; - framesize = roundup(maxargoffset + sizefsave + sizeisave + maxoffset, 16); - segment(CODE); - print(".ent %s\n", f->x.name); - print("%s:\n", f->x.name); - print("ldgp $gp,0($27)\n"); - i = maxargoffset + sizefsave - framesize; - if (framesize > 0) - print("lda $sp,%d($sp)\n", -framesize); - if (usedmask[FREG]) - print(".fmask 0x%x,%d\n", usedmask[FREG], i - 8); - if (usedmask[IREG]) - print(".mask 0x%x,%d\n", usedmask[IREG], i + sizeisave - 8); - print(".frame $sp,%d,$26,%d\n", framesize, sizeargs); - - saved = maxargoffset; - for (i = 2; i <= 9; i++) - if (usedmask[FREG]&(1<<i)) { - print("stt $f%d,%d($sp)\n", i, saved); - saved += 8; - } - - for (i = 9; i <= 26; i++) - if (usedmask[IREG]&(1<<i)) { - print("stq $%d,%d($sp)\n", i, saved); - saved += 8; - } - for (i = 0; i < 6 && callee[i]; i++) { - r = argregs[i]; - if (r && r->x.regnode != callee[i]->x.regnode) { - Symbol out = callee[i]; - Symbol in = caller[i]; - int rn = r->x.regnode->number; - int rs = r->x.regnode->set; - int tyin = ttob(in->type); - - assert(out && in && r && r->x.regnode); - assert(out->sclass != REGISTER || out->x.regnode); - if (out->sclass == REGISTER) { - if (rs == FREG) - print("fmov $f%d,$f%d\n", rn, out->x.regnode->number); - else - print("mov $%d,$%d\n", rn, out->x.regnode->number); - - } else { - int off = in->x.offset + framesize; - if (rs == FREG && tyin == F+sizeop(8)) - print("stt $f%d,%d($sp)\n", rn, off); - else if (rs == FREG && tyin == F+sizeop(4)) - print("sts $f%d,%d($sp)\n", rn, off); - else { - int i, n = (in->type->size + 7)/8; - for (i = rn; i < rn+n && i <= 21; i++) - print("stq $%d,%d($sp)\n", i, off + (i-rn)*8); - } - - } - - } - } - if (varargs && callee[i-1]) { - i = callee[i-1]->x.offset + roundup(callee[i-1]->type->size, 8); - for (i = (48+i)/8; i < 6; i++) { - print("stq $%d,%d($sp)\n", i + 16, framesize - 48 + 8*i); - print("stt $f%d,%d($sp)\n", i + 16, framesize - 2*48 + 8*i); - } - } - print(".prologue 1\n"); - - emitcode(); - saved = maxargoffset; - for (i = 2; i <= 9; i++) - if (usedmask[FREG]&(1<<i)) { - print("ldt $f%d,%d($sp)\n", i, saved); - saved += 8; - } - for (i = 9; i <= 26; i++) - if (usedmask[IREG]&(1<<i)) { - print("ldq $%d,%d($sp)\n", i, saved); - saved += 8; - } - if (framesize > 0) - print("lda $sp,%d($sp)\n", framesize); - print("ret\n"); - print(".end %s\n", f->x.name); - -} - -static void defconst(int suffix, int size, Value v) { - if (suffix == F && size == 4) { - float f = v.d; - print(".long 0x%x\n", *(unsigned *)&f); - } else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print(".long 0x%x\n.long 0x%x\n", p[swap], p[!swap]); - } else if (suffix == P) - print(".quad 0x%X\n", v.p); - else if (size == 1) - print(".byte 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 2) - print(".word 0x%x\n", suffix == I ? v.i&0xFFFF : v.u&0xFFFF); - else if (size == 4) - print(".long 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 8) - print(".quad 0x%X\n", suffix == I ? v.i : v.u); - -} - -static void defaddress(Symbol p) { - print(".quad %s\n", p->x.name); -} - -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print(".byte %d\n", (*s)&0377); -} - -static void export(Symbol p) { - print(".globl %s\n", p->x.name); -} - -static void import(Symbol p) { - if (!isfunc(p->type)) - print(".extern %s %d\n", p->name, p->type->size); -} - -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("L.%d", genlabel(1)); - else if (p->generated) - p->x.name = stringf("L.%s", p->name); - else - assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), - p->x.name = p->name; -} - -static void address(Symbol q, Symbol p, long n) { - if (p->scope == GLOBAL - || p->sclass == STATIC || p->sclass == EXTERN) - q->x.name = stringf("%s%s%D", p->x.name, - n >= 0 ? "+" : "", n); - else { - assert(n <= INT_MAX && n >= INT_MIN); - q->x.offset = p->x.offset + n; - q->x.name = stringd(q->x.offset); - } -} - -static void global(Symbol p) { - if (p->u.seg == DATA || p->u.seg == LIT) { - assert(p->type->align <= 8); - print(".align %c\n", ".01.2...3"[p->type->align]); - print("%s:\n", p->x.name); - } else if (p->sclass == STATIC || Aflag >= 2) - print(".lcomm %s,%d\n", p->x.name, p->type->size); - else - print( ".comm %s,%d\n", p->x.name, p->type->size); -} - -static void segment(int n) { - cseg = n; - switch (n) { - case DATA: print(".sdata\n"); break; - case CODE: print(".text\n"); break; - case LIT: print(".rdata\n"); break; - } -} - -static void space(int n) { - if (cseg != BSS) - print(".space %d\n", n); -} - -static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) { - int lab = genlabel(1); - - print("addq $%d,%d,$%d\n", sreg, size&~7, sreg); - print("addq $%d,%d,$%d\n", dreg, size&~7, tmps[2]); - blkcopy(tmps[2], doff, sreg, soff, size&7, tmps); - print("L.%d:\n", lab); - print("addq $%d,%d,$%d\n", sreg, -8, sreg); - print("addq $%d,%d,$%d\n", tmps[2], -8, tmps[2]); - blkcopy(tmps[2], doff, sreg, soff, 8, tmps); - print("cmpult $%d,$%d,$23\nbne $23,L.%d\n", dreg, tmps[2], lab); -} - -static void blkfetch(int size, int off, int reg, int tmp) { - assert(size == 1 || size == 2 || size == 4 || size == 8); - if (size == 1) - print("ldb $%d,%d($%d)\n", tmp, off, reg); - else if (size == 2) - print("ldw $%d,%d($%d)\n", tmp, off, reg); - else if (salign >= size && size == 4) - print("ldl $%d,%d($%d)\n", tmp, off, reg); - else if (salign >= size && size == 8) - print("ldq $%d,%d($%d)\n", tmp, off, reg); - else if (size == 4) - print("uldl $%d,%d($%d)\n", tmp, off, reg); - else - print("uldq $%d,%d($%d)\n", tmp, off, reg); -} - -static void blkstore(int size, int off, int reg, int tmp) { - assert(size == 1 || size == 2 || size == 4 || size == 8); - if (size == 1) - print("stb $%d,%d($%d)\n", tmp, off, reg); - else if (size == 2) - print("stw $%d,%d($%d)\n", tmp, off, reg); - else if (dalign >= size && size == 4) - print("stl $%d,%d($%d)\n", tmp, off, reg); - else if (dalign >= size && size == 8) - print("stq $%d,%d($%d)\n", tmp, off, reg); - else if (size == 4) - print("ustl $%d,%d($%d)\n", tmp, off, reg); - else - print("ustq $%d,%d($%d)\n", tmp, off, reg); -} - -/* stabinit - initialize stab output */ -static void stabinit(char *file, int argc, char *argv[]) { - if (file) { - print(".file 2,\"%s\"\n", file); - currentfile = file; - } -} - -/* stabline - emit stab entry for source coordinate *cp */ -static void stabline(Coordinate *cp) { - if (cp->file && cp->file != currentfile) { - print(".file 2,\"%s\"\n", cp->file); - currentfile = cp->file; - } - print(".loc 2,%d\n", cp->y); -} - -/* stabsym - output a stab entry for symbol p */ -static void stabsym(Symbol p) { - if (p == cfunc && IR->stabline) - (*IR->stabline)(&p->src); -} -Interface alphaIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 8, 8, 0, /* long */ - 8, 8, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 8, 8, 0, /* T * */ - 0, 1, 0, /* struct */ - - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - 0, 0, 0, stabinit, stabline, stabsym, 0, - { - 1, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } - -}; - - -static char rcsid[] = "$Id: alpha.md 145 2001-10-17 21:53:10Z timo $"; - diff --git a/code/tools/lcc/src/bind.c b/code/tools/lcc/src/bind.c index c27036f..bc7b983 100644 --- a/code/tools/lcc/src/bind.c +++ b/code/tools/lcc/src/bind.c @@ -1,22 +1,7 @@ #include "c.h" -extern Interface alphaIR; -extern Interface mipsebIR, mipselIR; -extern Interface sparcIR, solarisIR; -extern Interface x86IR, x86linuxIR; -extern Interface symbolicIR, symbolic64IR; extern Interface nullIR; extern Interface bytecodeIR; Binding bindings[] = { - /*{ "alpha/osf", &alphaIR },*/ - /*{ "mips/irix", &mipsebIR },*/ - /*{ "mips/ultrix", &mipselIR },*/ - /*{ "sparc/sun", &sparcIR },*/ - /*{ "sparc/solaris", &solarisIR },*/ - /*{ "x86/win32", &x86IR },*/ - /*{ "x86/linux", &x86linuxIR },*/ - { "symbolic/osf", &symbolic64IR }, - { "symbolic/irix", &symbolicIR }, - { "symbolic", &symbolicIR }, { "null", &nullIR }, { "bytecode", &bytecodeIR }, { NULL, NULL }, diff --git a/code/tools/lcc/src/mips.md b/code/tools/lcc/src/mips.md deleted file mode 100644 index 41f6d8c..0000000 --- a/code/tools/lcc/src/mips.md +++ /dev/null @@ -1,1120 +0,0 @@ -%{ -#define INTTMP 0x0100ff00 -#define INTVAR 0x40ff0000 -#define FLTTMP 0x000f0ff0 -#define FLTVAR 0xfff00000 - -#define INTRET 0x00000004 -#define FLTRET 0x00000003 - -#define readsreg(p) \ - (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P) -#define setsrc(d) ((d) && (d)->x.regnode && \ - (d)->x.regnode->set == src->x.regnode->set && \ - (d)->x.regnode->mask&src->x.regnode->mask) - -#define relink(a, b) ((b)->x.prev = (a), (a)->x.next = (b)) - -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -static void address(Symbol, Symbol, long); -static void blkfetch(int, int, int, int); -static void blkloop(int, int, int, int, int, int[]); -static void blkstore(int, int, int, int); -static void defaddress(Symbol); -static void defconst(int, int, Value); -static void defstring(int, char *); -static void defsymbol(Symbol); -static void doarg(Node); -static void emit2(Node); -static void export(Symbol); -static void clobber(Node); -static void function(Symbol, Symbol [], Symbol [], int); -static void global(Symbol); -static void import(Symbol); -static void local(Symbol); -static void progbeg(int, char **); -static void progend(void); -static void segment(int); -static void space(int); -static void target(Node); -static int bitcount (unsigned); -static Symbol argreg (int, int, int, int, int); - -static Symbol ireg[32], freg2[32], d6; -static Symbol iregw, freg2w; -static int tmpregs[] = {3, 9, 10}; -static Symbol blkreg; - -static int gnum = 8; -static int pic; - -static int cseg; -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRF4(VREGP) "# read register\n" -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRF8(VREGP) "# read register\n" -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" -con: CNSTI1 "%a" -con: CNSTU1 "%a" - -con: CNSTI2 "%a" -con: CNSTU2 "%a" - -con: CNSTI4 "%a" -con: CNSTU4 "%a" -con: CNSTP4 "%a" - -con: CNSTI8 "%a" -con: CNSTU8 "%a" -con: CNSTP8 "%a" -stmt: reg "" -acon: con "%0" -acon: ADDRGP4 "%a" -addr: ADDI4(reg,acon) "%1($%0)" -addr: ADDU4(reg,acon) "%1($%0)" -addr: ADDP4(reg,acon) "%1($%0)" -addr: acon "%0" -addr: reg "($%0)" -addr: ADDRFP4 "%a+%F($sp)" -addr: ADDRLP4 "%a+%F($sp)" -reg: addr "la $%c,%0\n" 1 -reg: CNSTI1 "# reg\n" range(a, 0, 0) -reg: CNSTI2 "# reg\n" range(a, 0, 0) -reg: CNSTI4 "# reg\n" range(a, 0, 0) -reg: CNSTU1 "# reg\n" range(a, 0, 0) -reg: CNSTU2 "# reg\n" range(a, 0, 0) -reg: CNSTU4 "# reg\n" range(a, 0, 0) -reg: CNSTP4 "# reg\n" range(a, 0, 0) -stmt: ASGNI1(addr,reg) "sb $%1,%0\n" 1 -stmt: ASGNU1(addr,reg) "sb $%1,%0\n" 1 -stmt: ASGNI2(addr,reg) "sh $%1,%0\n" 1 -stmt: ASGNU2(addr,reg) "sh $%1,%0\n" 1 -stmt: ASGNI4(addr,reg) "sw $%1,%0\n" 1 -stmt: ASGNU4(addr,reg) "sw $%1,%0\n" 1 -stmt: ASGNP4(addr,reg) "sw $%1,%0\n" 1 -reg: INDIRI1(addr) "lb $%c,%0\n" 1 -reg: INDIRU1(addr) "lbu $%c,%0\n" 1 -reg: INDIRI2(addr) "lh $%c,%0\n" 1 -reg: INDIRU2(addr) "lhu $%c,%0\n" 1 -reg: INDIRI4(addr) "lw $%c,%0\n" 1 -reg: INDIRU4(addr) "lw $%c,%0\n" 1 -reg: INDIRP4(addr) "lw $%c,%0\n" 1 - -reg: CVII4(INDIRI1(addr)) "lb $%c,%0\n" 1 -reg: CVII4(INDIRI2(addr)) "lh $%c,%0\n" 1 -reg: CVUU4(INDIRU1(addr)) "lbu $%c,%0\n" 1 -reg: CVUU4(INDIRU2(addr)) "lhu $%c,%0\n" 1 -reg: CVUI4(INDIRU1(addr)) "lbu $%c,%0\n" 1 -reg: CVUI4(INDIRU2(addr)) "lhu $%c,%0\n" 1 -reg: INDIRF4(addr) "l.s $f%c,%0\n" 1 -reg: INDIRF8(addr) "l.d $f%c,%0\n" 1 -stmt: ASGNF4(addr,reg) "s.s $f%1,%0\n" 1 -stmt: ASGNF8(addr,reg) "s.d $f%1,%0\n" 1 -reg: DIVI4(reg,reg) "div $%c,$%0,$%1\n" 1 -reg: DIVU4(reg,reg) "divu $%c,$%0,$%1\n" 1 -reg: MODI4(reg,reg) "rem $%c,$%0,$%1\n" 1 -reg: MODU4(reg,reg) "remu $%c,$%0,$%1\n" 1 -reg: MULI4(reg,reg) "mul $%c,$%0,$%1\n" 1 -reg: MULU4(reg,reg) "mul $%c,$%0,$%1\n" 1 -rc: con "%0" -rc: reg "$%0" - -reg: ADDI4(reg,rc) "addu $%c,$%0,%1\n" 1 -reg: ADDP4(reg,rc) "addu $%c,$%0,%1\n" 1 -reg: ADDU4(reg,rc) "addu $%c,$%0,%1\n" 1 -reg: BANDI4(reg,rc) "and $%c,$%0,%1\n" 1 -reg: BORI4(reg,rc) "or $%c,$%0,%1\n" 1 -reg: BXORI4(reg,rc) "xor $%c,$%0,%1\n" 1 -reg: BANDU4(reg,rc) "and $%c,$%0,%1\n" 1 -reg: BORU4(reg,rc) "or $%c,$%0,%1\n" 1 -reg: BXORU4(reg,rc) "xor $%c,$%0,%1\n" 1 -reg: SUBI4(reg,rc) "subu $%c,$%0,%1\n" 1 -reg: SUBP4(reg,rc) "subu $%c,$%0,%1\n" 1 -reg: SUBU4(reg,rc) "subu $%c,$%0,%1\n" 1 -rc5: CNSTI4 "%a" range(a,0,31) -rc5: reg "$%0" - -reg: LSHI4(reg,rc5) "sll $%c,$%0,%1\n" 1 -reg: LSHU4(reg,rc5) "sll $%c,$%0,%1\n" 1 -reg: RSHI4(reg,rc5) "sra $%c,$%0,%1\n" 1 -reg: RSHU4(reg,rc5) "srl $%c,$%0,%1\n" 1 -reg: BCOMI4(reg) "not $%c,$%0\n" 1 -reg: BCOMU4(reg) "not $%c,$%0\n" 1 -reg: NEGI4(reg) "negu $%c,$%0\n" 1 -reg: LOADI1(reg) "move $%c,$%0\n" move(a) -reg: LOADU1(reg) "move $%c,$%0\n" move(a) -reg: LOADI2(reg) "move $%c,$%0\n" move(a) -reg: LOADU2(reg) "move $%c,$%0\n" move(a) -reg: LOADI4(reg) "move $%c,$%0\n" move(a) -reg: LOADP4(reg) "move $%c,$%0\n" move(a) -reg: LOADU4(reg) "move $%c,$%0\n" move(a) -reg: ADDF4(reg,reg) "add.s $f%c,$f%0,$f%1\n" 1 -reg: ADDF8(reg,reg) "add.d $f%c,$f%0,$f%1\n" 1 -reg: DIVF4(reg,reg) "div.s $f%c,$f%0,$f%1\n" 1 -reg: DIVF8(reg,reg) "div.d $f%c,$f%0,$f%1\n" 1 -reg: MULF4(reg,reg) "mul.s $f%c,$f%0,$f%1\n" 1 -reg: MULF8(reg,reg) "mul.d $f%c,$f%0,$f%1\n" 1 -reg: SUBF4(reg,reg) "sub.s $f%c,$f%0,$f%1\n" 1 -reg: SUBF8(reg,reg) "sub.d $f%c,$f%0,$f%1\n" 1 -reg: LOADF4(reg) "mov.s $f%c,$f%0\n" move(a) -reg: LOADF8(reg) "mov.d $f%c,$f%0\n" move(a) -reg: NEGF4(reg) "neg.s $f%c,$f%0\n" 1 -reg: NEGF8(reg) "neg.d $f%c,$f%0\n" 1 -reg: CVII4(reg) "sll $%c,$%0,8*(4-%a); sra $%c,$%c,8*(4-%a)\n" 2 -reg: CVUI4(reg) "and $%c,$%0,(1<<(8*%a))-1\n" 1 -reg: CVUU4(reg) "and $%c,$%0,(1<<(8*%a))-1\n" 1 -reg: CVFF4(reg) "cvt.s.d $f%c,$f%0\n" 1 -reg: CVFF8(reg) "cvt.d.s $f%c,$f%0\n" 1 -reg: CVIF4(reg) "mtc1 $%0,$f%c; cvt.s.w $f%c,$f%c\n" 2 -reg: CVIF8(reg) "mtc1 $%0,$f%c; cvt.d.w $f%c,$f%c\n" 2 -reg: CVFI4(reg) "trunc.w.s $f2,$f%0,$%c; mfc1 $%c,$f2\n" (a->syms[0]->u.c.v.i==4?2:LBURG_MAX) -reg: CVFI4(reg) "trunc.w.d $f2,$f%0,$%c; mfc1 $%c,$f2\n" (a->syms[0]->u.c.v.i==8?2:LBURG_MAX) -stmt: LABELV "%a:\n" -stmt: JUMPV(acon) "b %0\n" 1 -stmt: JUMPV(reg) ".cpadd $%0\nj $%0\n" !pic -stmt: JUMPV(reg) "j $%0\n" pic -stmt: EQI4(reg,reg) "beq $%0,$%1,%a\n" 1 -stmt: EQU4(reg,reg) "beq $%0,$%1,%a\n" 1 -stmt: GEI4(reg,reg) "bge $%0,$%1,%a\n" 1 -stmt: GEU4(reg,reg) "bgeu $%0,$%1,%a\n" 1 -stmt: GTI4(reg,reg) "bgt $%0,$%1,%a\n" 1 -stmt: GTU4(reg,reg) "bgtu $%0,$%1,%a\n" 1 -stmt: LEI4(reg,reg) "ble $%0,$%1,%a\n" 1 -stmt: LEU4(reg,reg) "bleu $%0,$%1,%a\n" 1 -stmt: LTI4(reg,reg) "blt $%0,$%1,%a\n" 1 -stmt: LTU4(reg,reg) "bltu $%0,$%1,%a\n" 1 -stmt: NEI4(reg,reg) "bne $%0,$%1,%a\n" 1 -stmt: NEU4(reg,reg) "bne $%0,$%1,%a\n" 1 -stmt: EQF4(reg,reg) "c.eq.s $f%0,$f%1; bc1t %a\n" 2 -stmt: EQF8(reg,reg) "c.eq.d $f%0,$f%1; bc1t %a\n" 2 -stmt: LEF4(reg,reg) "c.le.s $f%0,$f%1; bc1t %a\n" 2 -stmt: LEF8(reg,reg) "c.le.d $f%0,$f%1; bc1t %a\n" 2 -stmt: LTF4(reg,reg) "c.lt.s $f%0,$f%1; bc1t %a\n" 2 -stmt: LTF8(reg,reg) "c.lt.d $f%0,$f%1; bc1t %a\n" 2 -stmt: GEF4(reg,reg) "c.lt.s $f%0,$f%1; bc1f %a\n" 2 -stmt: GEF8(reg,reg) "c.lt.d $f%0,$f%1; bc1f %a\n" 2 -stmt: GTF4(reg,reg) "c.le.s $f%0,$f%1; bc1f %a\n" 2 -stmt: GTF8(reg,reg) "c.le.d $f%0,$f%1; bc1f %a\n" 2 -stmt: NEF4(reg,reg) "c.eq.s $f%0,$f%1; bc1f %a\n" 2 -stmt: NEF8(reg,reg) "c.eq.d $f%0,$f%1; bc1f %a\n" 2 -ar: ADDRGP4 "%a" - -reg: CALLF4(ar) "jal %0\n" 1 -reg: CALLF8(ar) "jal %0\n" 1 -reg: CALLI4(ar) "jal %0\n" 1 -reg: CALLP4(ar) "jal %0\n" 1 -reg: CALLU4(ar) "jal %0\n" 1 -stmt: CALLV(ar) "jal %0\n" 1 -ar: reg "$%0" -ar: CNSTP4 "%a" range(a, 0, 0x0fffffff) -stmt: RETF4(reg) "# ret\n" 1 -stmt: RETF8(reg) "# ret\n" 1 -stmt: RETI4(reg) "# ret\n" 1 -stmt: RETU4(reg) "# ret\n" 1 -stmt: RETP4(reg) "# ret\n" 1 -stmt: RETV(reg) "# ret\n" 1 -stmt: ARGF4(reg) "# arg\n" 1 -stmt: ARGF8(reg) "# arg\n" 1 -stmt: ARGI4(reg) "# arg\n" 1 -stmt: ARGP4(reg) "# arg\n" 1 -stmt: ARGU4(reg) "# arg\n" 1 - -stmt: ARGB(INDIRB(reg)) "# argb %0\n" 1 -stmt: ASGNB(reg,INDIRB(reg)) "# asgnb %0 %1\n" 1 -%% -static void progend(void){} -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - print(".set reorder\n"); - pic = !IR->little_endian; - parseflags(argc, argv); - for (i = 0; i < argc; i++) - if (strncmp(argv[i], "-G", 2) == 0) - gnum = atoi(argv[i] + 2); - else if (strcmp(argv[i], "-pic=1") == 0 - || strcmp(argv[i], "-pic=0") == 0) - pic = argv[i][5]-'0'; - for (i = 0; i < 31; i += 2) - freg2[i] = mkreg("%d", i, 3, FREG); - for (i = 0; i < 32; i++) - ireg[i] = mkreg("%d", i, 1, IREG); - ireg[29]->x.name = "sp"; - d6 = mkreg("6", 6, 3, IREG); - freg2w = mkwildcard(freg2); - iregw = mkwildcard(ireg); - tmask[IREG] = INTTMP; tmask[FREG] = FLTTMP; - vmask[IREG] = INTVAR; vmask[FREG] = FLTVAR; - blkreg = mkreg("8", 8, 7, IREG); -} -static Symbol rmap(int opk) { - switch (optype(opk)) { - case I: case U: case P: case B: - return iregw; - case F: - return freg2w; - default: - return 0; - } -} -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case CNST+I: case CNST+U: case CNST+P: - if (range(p, 0, 0) == 0) { - setreg(p, ireg[0]); - p->x.registered = 1; - } - break; - case CALL+V: - rtarget(p, 0, ireg[25]); - break; - case CALL+F: - rtarget(p, 0, ireg[25]); - setreg(p, freg2[0]); - break; - case CALL+I: case CALL+P: case CALL+U: - rtarget(p, 0, ireg[25]); - setreg(p, ireg[2]); - break; - case RET+F: - rtarget(p, 0, freg2[0]); - break; - case RET+I: case RET+U: case RET+P: - rtarget(p, 0, ireg[2]); - break; - case ARG+F: case ARG+I: case ARG+P: case ARG+U: { - static int ty0; - int ty = optype(p->op); - Symbol q; - - q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, opsize(p->op), ty0); - if (p->x.argno == 0) - ty0 = ty; - if (q && - !(ty == F && q->x.regnode->set == IREG)) - rtarget(p, 0, q); - break; - } - case ASGN+B: rtarget(p->kids[1], 0, blkreg); break; - case ARG+B: rtarget(p->kids[0], 0, blkreg); break; - } -} -static void clobber(Node p) { - assert(p); - switch (specific(p->op)) { - case CALL+F: - spill(INTTMP | INTRET, IREG, p); - spill(FLTTMP, FREG, p); - break; - case CALL+I: case CALL+P: case CALL+U: - spill(INTTMP, IREG, p); - spill(FLTTMP | FLTRET, FREG, p); - break; - case CALL+V: - spill(INTTMP | INTRET, IREG, p); - spill(FLTTMP | FLTRET, FREG, p); - break; - } -} -static void emit2(Node p) { - int dst, n, src, sz, ty; - static int ty0; - Symbol q; - - switch (specific(p->op)) { - case ARG+F: case ARG+I: case ARG+P: case ARG+U: - ty = optype(p->op); - sz = opsize(p->op); - if (p->x.argno == 0) - ty0 = ty; - q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, sz, ty0); - src = getregnum(p->x.kids[0]); - if (q == NULL && ty == F && sz == 4) - print("s.s $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i); - else if (q == NULL && ty == F) - print("s.d $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i); - else if (q == NULL) - print("sw $%d,%d($sp)\n", src, p->syms[2]->u.c.v.i); - else if (ty == F && sz == 4 && q->x.regnode->set == IREG) - print("mfc1 $%d,$f%d\n", q->x.regnode->number, src); - else if (ty == F && q->x.regnode->set == IREG) - print("mfc1.d $%d,$f%d\n", q->x.regnode->number, src); - break; - case ASGN+B: - dalign = salign = p->syms[1]->u.c.v.i; - blkcopy(getregnum(p->x.kids[0]), 0, - getregnum(p->x.kids[1]), 0, - p->syms[0]->u.c.v.i, tmpregs); - break; - case ARG+B: - dalign = 4; - salign = p->syms[1]->u.c.v.i; - blkcopy(29, p->syms[2]->u.c.v.i, - getregnum(p->x.kids[0]), 0, - p->syms[0]->u.c.v.i, tmpregs); - n = p->syms[2]->u.c.v.i + p->syms[0]->u.c.v.i; - dst = p->syms[2]->u.c.v.i; - for ( ; dst <= 12 && dst < n; dst += 4) - print("lw $%d,%d($sp)\n", (dst/4)+4, dst); - break; - } -} -static Symbol argreg(int argno, int offset, int ty, int sz, int ty0) { - assert((offset&3) == 0); - if (offset > 12) - return NULL; - else if (argno == 0 && ty == F) - return freg2[12]; - else if (argno == 1 && ty == F && ty0 == F) - return freg2[14]; - else if (argno == 1 && ty == F && sz == 8) - return d6; /* Pair! */ - else - return ireg[(offset/4) + 4]; -} -static void doarg(Node p) { - static int argno; - int align; - - if (argoffset == 0) - argno = 0; - p->x.argno = argno++; - align = p->syms[1]->u.c.v.i < 4 ? 4 : p->syms[1]->u.c.v.i; - p->syms[2] = intconst(mkactual(align, - p->syms[0]->u.c.v.i)); -} -static void local(Symbol p) { - if (askregvar(p, rmap(ttob(p->type))) == 0) - mkauto(p); -} -static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - int i, saved, sizefsave, sizeisave, varargs; - Symbol r, argregs[4]; - - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~(unsigned)0; - offset = maxoffset = maxargoffset = 0; - for (i = 0; callee[i]; i++) - ; - varargs = variadic(f->type) - || i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0; - for (i = 0; callee[i]; i++) { - Symbol p = callee[i]; - Symbol q = caller[i]; - assert(q); - offset = roundup(offset, q->type->align); - p->x.offset = q->x.offset = offset; - p->x.name = q->x.name = stringd(offset); - r = argreg(i, offset, optype(ttob(q->type)), q->type->size, optype(ttob(caller[0]->type))); - if (i < 4) - argregs[i] = r; - offset = roundup(offset + q->type->size, 4); - if (varargs) - p->sclass = AUTO; - else if (r && ncalls == 0 && - !isstruct(q->type) && !p->addressed && - !(isfloat(q->type) && r->x.regnode->set == IREG) -) { - p->sclass = q->sclass = REGISTER; - askregvar(p, r); - assert(p->x.regnode && p->x.regnode->vbl == p); - q->x = p->x; - q->type = p->type; - } - else if (askregvar(p, rmap(ttob(p->type))) - && r != NULL - && (isint(p->type) || p->type == q->type)) { - assert(q->sclass != REGISTER); - p->sclass = q->sclass = REGISTER; - q->type = p->type; - } - } - assert(!caller[i]); - offset = 0; - gencode(caller, callee); - if (ncalls) - usedmask[IREG] |= ((unsigned)1)<<31; - usedmask[IREG] &= 0xc0ff0000; - usedmask[FREG] &= 0xfff00000; - if (pic && ncalls) - usedmask[IREG] |= 1<<25; - maxargoffset = roundup(maxargoffset, usedmask[FREG] ? 8 : 4); - if (ncalls && maxargoffset < 16) - maxargoffset = 16; - sizefsave = 4*bitcount(usedmask[FREG]); - sizeisave = 4*bitcount(usedmask[IREG]); - framesize = roundup(maxargoffset + sizefsave - + sizeisave + maxoffset, 8); - segment(CODE); - print(".align 2\n"); - print(".ent %s\n", f->x.name); - print("%s:\n", f->x.name); - i = maxargoffset + sizefsave - framesize; - print(".frame $sp,%d,$31\n", framesize); - if (pic) - print(".set noreorder\n.cpload $25\n.set reorder\n"); - if (framesize > 0) - print("addu $sp,$sp,%d\n", -framesize); - if (usedmask[FREG]) - print(".fmask 0x%x,%d\n", usedmask[FREG], i - 8); - if (usedmask[IREG]) - print(".mask 0x%x,%d\n", usedmask[IREG], - i + sizeisave - 4); - saved = maxargoffset; - for (i = 20; i <= 30; i += 2) - if (usedmask[FREG]&(3<<i)) { - print("s.d $f%d,%d($sp)\n", i, saved); - saved += 8; - } - - for (i = 16; i <= 31; i++) - if (usedmask[IREG]&(1<<i)) { - if (i == 25) - print(".cprestore %d\n", saved); - else - print("sw $%d,%d($sp)\n", i, saved); - saved += 4; - } - for (i = 0; i < 4 && callee[i]; i++) { - r = argregs[i]; - if (r && r->x.regnode != callee[i]->x.regnode) { - Symbol out = callee[i]; - Symbol in = caller[i]; - int rn = r->x.regnode->number; - int rs = r->x.regnode->set; - int tyin = ttob(in->type); - - assert(out && in && r && r->x.regnode); - assert(out->sclass != REGISTER || out->x.regnode); - if (out->sclass == REGISTER - && (isint(out->type) || out->type == in->type)) { - int outn = out->x.regnode->number; - if (rs == FREG && tyin == F+sizeop(8)) - print("mov.d $f%d,$f%d\n", outn, rn); - else if (rs == FREG && tyin == F+sizeop(4)) - print("mov.s $f%d,$f%d\n", outn, rn); - else if (rs == IREG && tyin == F+sizeop(8)) - print("mtc1.d $%d,$f%d\n", rn, outn); - else if (rs == IREG && tyin == F+sizeop(4)) - print("mtc1 $%d,$f%d\n", rn, outn); - else - print("move $%d,$%d\n", outn, rn); - } else { - int off = in->x.offset + framesize; - if (rs == FREG && tyin == F+sizeop(8)) - print("s.d $f%d,%d($sp)\n", rn, off); - else if (rs == FREG && tyin == F+sizeop(4)) - print("s.s $f%d,%d($sp)\n", rn, off); - else { - int i, n = (in->type->size + 3)/4; - for (i = rn; i < rn+n && i <= 7; i++) - print("sw $%d,%d($sp)\n", i, off + (i-rn)*4); - } - } - } - } - if (varargs && callee[i-1]) { - i = callee[i-1]->x.offset + callee[i-1]->type->size; - for (i = roundup(i, 4)/4; i <= 3; i++) - print("sw $%d,%d($sp)\n", i + 4, framesize + 4*i); - } - emitcode(); - saved = maxargoffset; - for (i = 20; i <= 30; i += 2) - if (usedmask[FREG]&(3<<i)) { - print("l.d $f%d,%d($sp)\n", i, saved); - saved += 8; - } - for (i = 16; i <= 31; i++) - if (usedmask[IREG]&(1<<i)) { - print("lw $%d,%d($sp)\n", i, saved); - saved += 4; - } - if (framesize > 0) - print("addu $sp,$sp,%d\n", framesize); - print("j $31\n"); - print(".end %s\n", f->x.name); -} -static void defconst(int suffix, int size, Value v) { - if (suffix == F && size == 4) { - float f = v.d; - print(".word 0x%x\n", *(unsigned *)&f); - } - else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print(".word 0x%x\n.word 0x%x\n", p[swap], p[!swap]); - } - else if (suffix == P) - print(".word 0x%x\n", v.p); - else if (size == 1) - print(".byte 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 2) - print(".half 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 4) - print(".word 0x%x\n", suffix == I ? v.i : v.u); -} -static void defaddress(Symbol p) { - if (pic && p->scope == LABELS) - print(".gpword %s\n", p->x.name); - else - print(".word %s\n", p->x.name); -} -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print(".byte %d\n", (*s)&0377); -} -static void export(Symbol p) { - print(".globl %s\n", p->x.name); -} -static void import(Symbol p) { - if (!isfunc(p->type)) - print(".extern %s %d\n", p->name, p->type->size); -} -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("L.%d", genlabel(1)); - else if (p->generated) - p->x.name = stringf("L.%s", p->name); - else - assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), - p->x.name = p->name; -} -static void address(Symbol q, Symbol p, long n) { - if (p->scope == GLOBAL - || p->sclass == STATIC || p->sclass == EXTERN) - q->x.name = stringf("%s%s%D", p->x.name, - n >= 0 ? "+" : "", n); - else { - assert(n <= INT_MAX && n >= INT_MIN); - q->x.offset = p->x.offset + n; - q->x.name = stringd(q->x.offset); - } -} -static void global(Symbol p) { - if (p->u.seg == BSS) { - if (p->sclass == STATIC || Aflag >= 2) - print(".lcomm %s,%d\n", p->x.name, p->type->size); - else - print( ".comm %s,%d\n", p->x.name, p->type->size); - } else { - if (p->u.seg == DATA - && (p->type->size == 0 || p->type->size > gnum)) - print(".data\n"); - else if (p->u.seg == DATA) - print(".sdata\n"); - print(".align %c\n", ".01.2...3"[p->type->align]); - print("%s:\n", p->x.name); - } -} -static void segment(int n) { - cseg = n; - switch (n) { - case CODE: print(".text\n"); break; - case LIT: print(".rdata\n"); break; - } -} -static void space(int n) { - if (cseg != BSS) - print(".space %d\n", n); -} -static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) { - int lab = genlabel(1); - - print("addu $%d,$%d,%d\n", sreg, sreg, size&~7); - print("addu $%d,$%d,%d\n", tmps[2], dreg, size&~7); - blkcopy(tmps[2], doff, sreg, soff, size&7, tmps); - print("L.%d:\n", lab); - print("addu $%d,$%d,%d\n", sreg, sreg, -8); - print("addu $%d,$%d,%d\n", tmps[2], tmps[2], -8); - blkcopy(tmps[2], doff, sreg, soff, 8, tmps); - print("bltu $%d,$%d,L.%d\n", dreg, tmps[2], lab); -} -static void blkfetch(int size, int off, int reg, int tmp) { - assert(size == 1 || size == 2 || size == 4); - if (size == 1) - print("lbu $%d,%d($%d)\n", tmp, off, reg); - else if (salign >= size && size == 2) - print("lhu $%d,%d($%d)\n", tmp, off, reg); - else if (salign >= size) - print("lw $%d,%d($%d)\n", tmp, off, reg); - else if (size == 2) - print("ulhu $%d,%d($%d)\n", tmp, off, reg); - else - print("ulw $%d,%d($%d)\n", tmp, off, reg); -} -static void blkstore(int size, int off, int reg, int tmp) { - if (size == 1) - print("sb $%d,%d($%d)\n", tmp, off, reg); - else if (dalign >= size && size == 2) - print("sh $%d,%d($%d)\n", tmp, off, reg); - else if (dalign >= size) - print("sw $%d,%d($%d)\n", tmp, off, reg); - else if (size == 2) - print("ush $%d,%d($%d)\n", tmp, off, reg); - else - print("usw $%d,%d($%d)\n", tmp, off, reg); -} -static void stabinit(char *, int, char *[]); -static void stabline(Coordinate *); -static void stabsym(Symbol); - -static char *currentfile; - -static int bitcount(unsigned mask) { - unsigned i, n = 0; - - for (i = 1; i; i <<= 1) - if (mask&i) - n++; - return n; -} - -/* stabinit - initialize stab output */ -static void stabinit(char *file, int argc, char *argv[]) { - if (file) { - print(".file 2,\"%s\"\n", file); - currentfile = file; - } -} - -/* stabline - emit stab entry for source coordinate *cp */ -static void stabline(Coordinate *cp) { - if (cp->file && cp->file != currentfile) { - print(".file 2,\"%s\"\n", cp->file); - currentfile = cp->file; - } - print(".loc 2,%d\n", cp->y); -} - -/* stabsym - output a stab entry for symbol p */ -static void stabsym(Symbol p) { - if (p == cfunc && IR->stabline) - (*IR->stabline)(&p->src); -} -Interface mipsebIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 1, 0, /* struct */ - 0, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - 0, 0, 0, stabinit, stabline, stabsym, 0, - { - 4, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } -}, mipselIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 1, 0, /* struct */ - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - 0, 0, 0, stabinit, stabline, stabsym, 0, - { - 4, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } -}; -static char rcsid[] = "$Id: mips.md 145 2001-10-17 21:53:10Z timo $"; diff --git a/code/tools/lcc/src/pass2.c b/code/tools/lcc/src/pass2.c deleted file mode 100644 index 08d73cf..0000000 --- a/code/tools/lcc/src/pass2.c +++ /dev/null @@ -1,665 +0,0 @@ -#include "c.h" -#include "rcc.h" -#if WIN32 -#include <fcntl.h> -#include <io.h> -#endif - - -Interface *IR = NULL; -int Aflag; /* >= 0 if -A specified */ -int Pflag; /* != 0 if -P specified */ -int glevel; /* == [0-9] if -g[0-9] specified */ -int xref; /* != 0 for cross-reference data */ -Symbol YYnull; /* _YYnull symbol if -n or -nvalidate specified */ -Symbol YYcheck; /* _YYcheck symbol if -nvalidate,check specified */ - -static int verbose = 1; -#define VERBOSE(n,arg) (verbose >= n ? (void)(arg):(void)0) -static int nuids; -static rcc_item_ty *items; -static void **itemmap; - -static void *uid2type(int uid) { - assert(uid >= 0 && uid < nuids); - if (itemmap[uid] == NULL) { - Type ty; - rcc_type_ty type = (void *)items[uid]; - assert(items[uid]); - assert(items[uid]->uid == uid); - assert(items[uid]->kind == rcc_Type_enum); - type = items[uid]->v.rcc_Type.type; - assert(type); - switch (type->kind) { - case rcc_INT_enum: - ty = btot(INT, type->size); - assert(ty->align == type->align); - break; - case rcc_UNSIGNED_enum: - ty = btot(UNSIGNED, type->size); - assert(ty->align == type->align); - break; - case rcc_FLOAT_enum: - ty = btot(FLOAT, type->size); - assert(ty->align == type->align); - break; - case rcc_VOID_enum: - ty = voidtype; - break; - case rcc_POINTER_enum: - ty = ptr(uid2type(type->v.rcc_POINTER.type)); - break; - case rcc_ARRAY_enum: - ty = uid2type(type->v.rcc_ARRAY.type); - assert(ty->size > 0); - ty = array(ty, type->size/ty->size, 0); - break; - case rcc_CONST_enum: - ty = qual(CONST, uid2type(type->v.rcc_CONST.type)); - break; - case rcc_VOLATILE_enum: - ty = qual(VOLATILE, uid2type(type->v.rcc_VOLATILE.type)); - break; - case rcc_ENUM_enum: { - int i, n = Seq_length(type->v.rcc_ENUM.ids); - ty = newstruct(ENUM, string(type->v.rcc_ENUM.tag)); - ty->type = inttype; - ty->size = ty->type->size; - ty->align = ty->type->align; - ty->u.sym->u.idlist = newarray(n + 1, sizeof *ty->u.sym->u.idlist, PERM); - for (i = 0; i < n; i++) { - rcc_enum__ty e = Seq_remlo(type->v.rcc_ENUM.ids); - Symbol p = install(e->id, &identifiers, GLOBAL, PERM); - p->type = ty; - p->sclass = ENUM; - p->u.value = e->value; - ty->u.sym->u.idlist[i] = p; - free(e); - } - ty->u.sym->u.idlist[i] = NULL; - Seq_free(&type->v.rcc_ENUM.ids); - break; - } - case rcc_STRUCT_enum: case rcc_UNION_enum: { - int i, n; - Field *tail; - list_ty fields; - if (type->kind == rcc_STRUCT_enum) { - ty = newstruct(STRUCT, string(type->v.rcc_STRUCT.tag)); - fields = type->v.rcc_STRUCT.fields; - } else { - ty = newstruct(UNION, string(type->v.rcc_UNION.tag)); - fields = type->v.rcc_UNION.fields; - } - itemmap[uid] = ty; /* recursive types */ - ty->size = type->size; - ty->align = type->align; - tail = &ty->u.sym->u.s.flist; - n = Seq_length(fields); - for (i = 0; i < n; i++) { - rcc_field_ty field = Seq_remlo(fields); - NEW0(*tail, PERM); - (*tail)->name = (char *)field->id; - (*tail)->type = uid2type(field->type); - (*tail)->offset = field->offset; - (*tail)->bitsize = field->bitsize; - (*tail)->lsb = field->lsb; - if (isconst((*tail)->type)) - ty->u.sym->u.s.cfields = 1; - if (isvolatile((*tail)->type)) - ty->u.sym->u.s.vfields = 1; - tail = &(*tail)->link; - free(field); - } - Seq_free(&fields); - break; - } - case rcc_FUNCTION_enum: { - int n = Seq_length(type->v.rcc_FUNCTION.formals); - if (n > 0) { - int i; - Type *proto = newarray(n + 1, sizeof *proto, PERM); - for (i = 0; i < n; i++) { - int *formal = Seq_remlo(type->v.rcc_FUNCTION.formals); - proto[i] = uid2type(*formal); - free(formal); - } - proto[i] = NULL; - ty = func(uid2type(type->v.rcc_FUNCTION.type), proto, 0); - } else - ty = func(uid2type(type->v.rcc_FUNCTION.type), NULL, 1); - Seq_free(&type->v.rcc_FUNCTION.formals); - break; - } - default: assert(0); - } - if (itemmap[uid] == NULL) { - itemmap[uid] = ty; - free(type); - free(items[uid]); - items[uid] = NULL; - } else - assert(itemmap[uid] == ty); - } - return itemmap[uid]; -} - -static Symbol uid2symbol(int uid) { - assert(uid >= 0 && uid < nuids); - if (itemmap[uid] == NULL) { - Symbol p; - rcc_symbol_ty symbol; - assert(items[uid]); - assert(items[uid]->uid == uid); - assert(items[uid]->kind == rcc_Symbol_enum); - symbol = items[uid]->v.rcc_Symbol.symbol; - assert(symbol); - NEW0(p, PERM); - p->name = (char *)symbol->id; - p->scope = symbol->scope; - p->sclass = symbol->sclass; - p->type = uid2type(symbol->type); -#define xx(f,n) p->f = symbol->flags>>n; - xx(structarg,0) - xx(addressed,1) - xx(computed,2) - xx(temporary,3) - xx(generated,4) -#undef xx - p->ref = symbol->ref/10000.0; - assert(p->scope != CONSTANTS && p->scope != LABELS); - if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) - (*IR->defsymbol)(p); - itemmap[uid] = p; - free(symbol); - free(items[uid]); - items[uid] = NULL; - } - return itemmap[uid]; -} - -#define xx(s) static void do##s(rcc_interface_ty); -xx(Export) -xx(Import) -xx(Global) -xx(Local) -xx(Address) -xx(Segment) -xx(Defaddress) -xx(Deflabel) -xx(Defconst) -xx(Defconstf) -xx(Defstring) -xx(Space) -xx(Function) -xx(Blockbeg) -xx(Blockend) -xx(Forest) -#undef xx -static void (*doX[])(rcc_interface_ty in) = { -#define xx(s) 0, -xx(Export) -xx(Import) -xx(Global) -xx(Local) -xx(Address) -xx(Segment) -xx(Defaddress) -xx(Deflabel) -xx(Defconst) -xx(Defconstf) -xx(Defstring) -xx(Space) -xx(Function) -xx(Blockbeg) -xx(Blockend) -xx(Forest) - 0 -#undef xx -}; - -static void interface(rcc_interface_ty in) { - assert(in); - (*doX[in->kind])(in); - free(in); -} - -static void doExport(rcc_interface_ty in) { - (*IR->export)(uid2symbol(in->v.rcc_Export.p)); -} - -static void doImport(rcc_interface_ty in) { - Symbol p = uid2symbol(in->v.rcc_Export.p); - - (*IR->import)(p); - p->defined = 1; -} - -static void doGlobal(rcc_interface_ty in) { - Symbol p = uid2symbol(in->v.rcc_Global.p); - - p->u.seg = in->v.rcc_Global.seg; - (*IR->global)(p); - p->defined = 1; -} - -static void doLocal(rcc_interface_ty in) { - int uid = in->v.rcc_Local.uid; - - assert(uid >= 0 && uid < nuids); - assert(items[uid] == NULL); - items[uid] = rcc_Symbol(uid, in->v.rcc_Local.p); - if (in->v.rcc_Local.p->scope >= LOCAL) - addlocal(uid2symbol(uid)); -} - -static void doAddress(rcc_interface_ty in) { - int uid = in->v.rcc_Address.uid; - Symbol p = uid2symbol(in->v.rcc_Address.p); - - assert(uid >= 0 && uid < nuids); - assert(items[uid] == NULL); - items[uid] = rcc_Symbol(uid, in->v.rcc_Address.q); - if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) - (*IR->address)(uid2symbol(uid), p, in->v.rcc_Address.n); - else { - Code cp = code(Address); - cp->u.addr.sym = uid2symbol(uid); - cp->u.addr.base = p; - cp->u.addr.offset = in->v.rcc_Address.n; - } -} - -static void doSegment(rcc_interface_ty in) { - (*IR->segment)(in->v.rcc_Segment.seg); -} - -static void doDefaddress(rcc_interface_ty in) { - (*IR->defaddress)(uid2symbol(in->v.rcc_Defaddress.p)); -} - -static void doDeflabel(rcc_interface_ty in) { - (*IR->defaddress)(findlabel(in->v.rcc_Deflabel.label)); -} - -static void doDefconst(rcc_interface_ty in) { - Value v; - - v.i = in->v.rcc_Defconst.value; - (*IR->defconst)(in->v.rcc_Defconst.suffix, in->v.rcc_Defconst.size, v); -} - -static void doDefconstf(rcc_interface_ty in) { - Value v; - unsigned *p = (unsigned *)&v.d; - - p[swap] = in->v.rcc_Defconstf.value->msb; - p[1-swap] = in->v.rcc_Defconstf.value->lsb; - (*IR->defconst)(F, in->v.rcc_Defconstf.size, v); - free(in->v.rcc_Defconstf.value); -} - -static void doDefstring(rcc_interface_ty in) { - (*IR->defstring)(in->v.rcc_Defstring.s.len, (char *)in->v.rcc_Defstring.s.str); - free((char *)in->v.rcc_Defstring.s.str); -} - -static void doSpace(rcc_interface_ty in) { - (*IR->space)(in->v.rcc_Space.n); -} - -static void doFunction(rcc_interface_ty in) { - int i, n; - Symbol *caller, *callee; - - /* - Initialize: - define the function symbol, - initialize callee and caller arrays. - */ - cfunc = uid2symbol(in->v.rcc_Function.f); - labels = table(NULL, LABELS); - enterscope(); - n = Seq_length(in->v.rcc_Function.caller); - caller = newarray(n + 1, sizeof *caller, FUNC); - for (i = 0; i < n; i++) { - int *uid = Seq_remlo(in->v.rcc_Function.caller); - caller[i] = uid2symbol(*uid); - free(uid); - } - caller[i] = NULL; - Seq_free(&in->v.rcc_Function.caller); - callee = newarray(n + 1, sizeof *callee, FUNC); - for (i = 0; i < n; i++) { - int *uid = Seq_remlo(in->v.rcc_Function.callee); - callee[i] = uid2symbol(*uid); - free(uid); - } - callee[i] = NULL; - Seq_free(&in->v.rcc_Function.callee); - cfunc->u.f.callee = callee; - cfunc->defined = 1; - /* - Initialize the code list, - traverse the interfaces inside the function; - each call appends code list entries. - */ - codelist = &codehead; - codelist->next = NULL; - n = Seq_length(in->v.rcc_Function.codelist); - for (i = 0; i < n; i++) - interface(Seq_remlo(in->v.rcc_Function.codelist)); - Seq_free(&in->v.rcc_Function.codelist); - /* - Call the back end, - Wrap-up. - */ - exitscope(); - (*IR->function)(cfunc, caller, callee, in->v.rcc_Function.ncalls); - cfunc = NULL; - labels = NULL; -} - -static struct block { - Code begin; - struct block *prev; -} *blockstack = NULL; - -static void doBlockbeg(rcc_interface_ty in) { - struct block *b; - Code cp = code(Blockbeg); - - enterscope(); - cp->u.block.level = level; - cp->u.block.locals = newarray(1, sizeof *cp->u.block.locals, FUNC); - cp->u.block.locals[0] = NULL; - cp->u.block.identifiers = NULL; - cp->u.block.types = NULL; - NEW(b, FUNC); - b->begin = cp; - b->prev = blockstack; - blockstack = b; -} - -static void doBlockend(rcc_interface_ty in) { - assert(blockstack); - code(Blockend)->u.begin = blockstack->begin; - blockstack = blockstack->prev; - exitscope(); -} - -static Node visit(rcc_node_ty node) { - int op; - Node left = NULL, right = NULL, p = NULL; - Symbol sym = NULL; - - switch (node->kind) { -#define T(x) rcc_##x##_enum - case T(CSE): { - Symbol q = uid2symbol(node->v.rcc_CSE.uid); - assert(q->temporary); - q->u.t.cse = p = visit(node->v.rcc_CSE.node); - break; - } - case T(CNST): { - Value v; - v.i = node->v.rcc_CNST.value; - sym = constant(btot(node->suffix, node->size), v); - op = CNST; - break; - } - case T(CNSTF): { - Value v; - unsigned *p = (unsigned *)&v.d; - p[swap] = node->v.rcc_CNSTF.value->msb; - p[1-swap] = node->v.rcc_CNSTF.value->lsb; - sym = constant(btot(node->suffix, node->size), v); - free(node->v.rcc_CNSTF.value); - op = CNST; - break; - } - case T(ARG): - p = newnode(ARG + node->suffix + sizeop(node->size), - visit(node->v.rcc_ARG.left), NULL, - intconst(node->v.rcc_ARG.len)); - p->syms[1] = intconst(node->v.rcc_ARG.align); - break; - case T(ASGN): - p = newnode(ASGN + node->suffix + sizeop(node->size), - visit(node->v.rcc_ASGN.left), visit(node->v.rcc_ASGN.right), - intconst(node->v.rcc_ASGN.len)); - p->syms[1] = intconst(node->v.rcc_ASGN.align); - break; - case T(CVT): - op = node->v.rcc_CVT.op; - left = visit(node->v.rcc_CVT.left); - sym = intconst(node->v.rcc_CVT.fromsize); - break; - case T(CALL): - op = CALL; - left = visit(node->v.rcc_CALL.left); - NEW0(sym, FUNC); - sym->type = uid2type(node->v.rcc_CALL.type); - break; - case T(CALLB): - op = CALL; - left = visit(node->v.rcc_CALLB.left); - right = visit(node->v.rcc_CALLB.right); - NEW0(sym, FUNC); - sym->type = uid2type(node->v.rcc_CALLB.type); - break; - case T(RET): - op = RET; - break; - case T(ADDRG): - op = ADDRG; - sym = uid2symbol(node->v.rcc_ADDRG.uid); - break; - case T(ADDRL): - op = ADDRL; - sym = uid2symbol(node->v.rcc_ADDRG.uid); - break; - case T(ADDRF): - op = ADDRF; - sym = uid2symbol(node->v.rcc_ADDRG.uid); - break; - case T(Unary): - op = node->v.rcc_Unary.op; - left = visit(node->v.rcc_Unary.left); - break; - case T(Binary): - op = node->v.rcc_Binary.op; - left = visit(node->v.rcc_Binary.left); - right = visit(node->v.rcc_Binary.right); - break; - case T(Compare): - op = node->v.rcc_Compare.op; - left = visit(node->v.rcc_Compare.left); - right = visit(node->v.rcc_Compare.right); - sym = findlabel(node->v.rcc_Compare.label); - break; - case T(LABEL): - op = LABEL; - sym = findlabel(node->v.rcc_LABEL.label); - break; - case T(BRANCH): - op = JUMP; - left = newnode(ADDRG+P+sizeop(voidptype->size), NULL, NULL, findlabel(node->v.rcc_BRANCH.label)); - break; -#undef T - default: assert(0); - } - if (p == NULL) - p = newnode(op + node->suffix + sizeop(node->size), left, right, sym); - free(node); - return p; -} - -static void doForest(rcc_interface_ty in) { - Node *tail = &code(Gen)->u.forest; - int i, n = Seq_length(in->v.rcc_Forest.nodes); - - for (i = 0; i < n; i++) { - *tail = visit(Seq_remlo(in->v.rcc_Forest.nodes)); - assert(*tail); - tail = &(*tail)->link; - } - *tail = NULL; - Seq_free(&in->v.rcc_Forest.nodes); -} - -int main(int argc, char *argv[]) { - int i, version; - float stamp = (assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL)) -; - char *infile = NULL, *outfile = NULL; - rcc_program_ty pickle; - - for (i = 1; i < argc; i++) - if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) { - if (infile == NULL) - infile = argv[i]; - else if (outfile == NULL) - outfile = argv[i]; - } - if (infile != NULL && strcmp(infile, "-") != 0 - && freopen(infile, "rb", stdin) == NULL) { - fprint(stderr, "%s: can't read `%s'\n", argv[0], infile); - exit(EXIT_FAILURE); - } -#if WIN32 - else - _setmode(_fileno(stdin), _O_BINARY); -#endif - if (outfile != NULL && strcmp(outfile, "-") != 0 - && freopen(outfile, "w", stdout) == NULL) { - fprint(stderr, "%s: can't write `%s'\n", argv[0], outfile); - exit(EXIT_FAILURE); - } - version = read_int(stdin); - assert(version/100 == (int)stamp); - pickle = rcc_read_program(stdin); - argc = pickle->argc; - argv = newarray(argc + 1, sizeof *argv, PERM); - { - for (i = 0; i < argc; i++) { - string_ty *arg = Seq_remlo(pickle->argv); - argv[i] = (char *)arg->str; - free(arg); - } - argv[i] = NULL; - assert(i == argc); - Seq_free(&pickle->argv); - } - for (i = argc - 1; i > 0; i--) - if (strncmp(argv[i], "-target=", 8) == 0) - break; - if (i > 0) { - int j; - for (j = 0; bindings[j].name && bindings[j].ir; j++) - if (strcmp(&argv[i][8], bindings[j].name) == 0) { - IR = bindings[j].ir; - break; - } - } - if (!IR) { - fprint(stderr, "%s: unknown target", argv[0]); - if (i > 0) - fprint(stderr, " `%s'", &argv[i][8]); - fprint(stderr, "; must specify one of\n"); - for (i = 0; bindings[i].name; i++) - fprint(stderr, "\t-target=%s\n", bindings[i].name); - exit(EXIT_FAILURE); - } - IR->wants_dag = 0; /* pickle's hold trees */ - init(argc, argv); - genlabel(pickle->nlabels); - level = GLOBAL; - { - int i, count; - nuids = pickle->nuids; - items = newarray(nuids, sizeof *items, PERM); - itemmap = newarray(nuids, sizeof *items, PERM); - for (i = 0; i < nuids; i++) { - itemmap[i] = NULL; - items[i] = NULL; - } - (*IR->progbeg)(argc, argv); - count = Seq_length(pickle->items); - for (i = 0; i < count; i++) { - rcc_item_ty item = Seq_remlo(pickle->items); - int uid = item->uid; - assert(uid >= 0 && uid < nuids); - assert(items[uid] == NULL); - items[uid] = item; - } - Seq_free(&pickle->items); -#define xx(s) assert(rcc_##s##_enum < sizeof doX/sizeof doX[0] && doX[rcc_##s##_enum]==0); \ - doX[rcc_##s##_enum] = do##s; - xx(Export) - xx(Import) - xx(Global) - xx(Local) - xx(Address) - xx(Segment) - xx(Defaddress) - xx(Deflabel) - xx(Defconst) - xx(Defconstf) - xx(Defstring) - xx(Space) - xx(Function) - xx(Blockbeg) - xx(Blockend) - xx(Forest) -#undef xx - count = Seq_length(pickle->interfaces); - for (i = 0; i < count; i++) - interface(Seq_remlo(pickle->interfaces)); - Seq_free(&pickle->interfaces); - free(pickle); - (*IR->progend)(); - } - deallocate(PERM); - return errcnt > 0; -} - -/* main_init - process program arguments */ -void main_init(int argc, char *argv[]) { - int i; - static int inited; - - if (inited) - return; - inited = 1; - for (i = 1; i < argc; i++) - if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "-g2") == 0) - glevel = 2; - else if (strcmp(argv[i], "-w") == 0) - wflag++; - else if (strcmp(argv[i], "-v") == 0) { - fprint(stderr, "%s %s\n", argv[0], rcsid); - verbose++; - } else if (strncmp(argv[i], "-errout=", 8) == 0) { - FILE *f = fopen(argv[i]+8, "w"); - if (f == NULL) { - fprint(stderr, "%s: can't write errors to `%s'\n", argv[0], argv[i]+8); - exit(EXIT_FAILURE); - } - fclose(f); - f = freopen(argv[i]+8, "w", stderr); - assert(f); - } else if (strncmp(argv[i], "-e", 2) == 0) { - int x; - if ((x = strtol(&argv[i][2], NULL, 0)) > 0) - errlimit = x; - } -} - -void init(int argc, char *argv[]) { - {extern void main_init(int, char *[]); main_init(argc, argv);} - {extern void prof_init(int, char *[]); prof_init(argc, argv);} - {extern void trace_init(int, char *[]); trace_init(argc, argv);} - {extern void type_init(int, char *[]); type_init(argc, argv);} - {extern void x86linux_init(int, char *[]); x86linux_init(argc, argv);} -} diff --git a/code/tools/lcc/src/sparc.md b/code/tools/lcc/src/sparc.md deleted file mode 100644 index f956d46..0000000 --- a/code/tools/lcc/src/sparc.md +++ /dev/null @@ -1,1163 +0,0 @@ -%{ -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -static void address(Symbol, Symbol, long); -static void blkfetch(int, int, int, int); -static void blkloop(int, int, int, int, int, int[]); -static void blkstore(int, int, int, int); -static void defaddress(Symbol); -static void defconst(int, int, Value); -static void defstring(int, char *); -static void defsymbol(Symbol); -static void doarg(Node); -static void emit2(Node); -static void export(Symbol); -static void clobber(Node); -static void function(Symbol, Symbol [], Symbol [], int); -static void global(Symbol); -static void import(Symbol); -static void local(Symbol); -static void progbeg(int, char **); -static void progend(void); -static void segment(int); -static void space(int); -static void target(Node); -static int imm(Node); -static void renameregs(void); -extern Interface sparcIR, solarisIR; -static void defsymbol2(Symbol); -static void export2(Symbol); -static void globalend(void); -static void global2(Symbol); -static void segment2(int); -static void progend2(void); - -extern char *stabprefix; -extern void stabblock(int, int, Symbol*); -extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *); -extern void stabfend(Symbol, int); -extern void stabinit(char *, int, char *[]); -extern void stabline(Coordinate *); -extern void stabsym(Symbol); -extern void stabtype(Symbol); -static Symbol greg[32], gregw; -static Symbol *oreg = &greg[8], *ireg = &greg[24]; -static Symbol freg[32], freg2[32]; -static Symbol fregw, freg2w; - -static int regvars; -static int retstruct; - -static int pflag = 0; - -static int cseg; - -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRF4(VREGP) "# read register\n" -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRF8(VREGP) "# read register\n" -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" -con: CNSTI1 "%a" -con: CNSTU1 "%a" - -con: CNSTI2 "%a" -con: CNSTU2 "%a" - -con: CNSTI4 "%a" -con: CNSTU4 "%a" -con: CNSTP4 "%a" - -con: CNSTI8 "%a" -con: CNSTU8 "%a" -con: CNSTP8 "%a" -stmt: reg "" -reg: ADDRGP4 "set %a,%%%c\n" 1 -stk13: ADDRFP4 "%a" imm(a) -stk13: ADDRLP4 "%a" imm(a) -reg: stk13 "add %0,%%fp,%%%c\n" 1 -stk: ADDRFP4 "set %a,%%%c\n" 2 -stk: ADDRLP4 "set %a,%%%c\n" 2 -reg: ADDRFP4 "set %a,%%%c\nadd %%%c,%%fp,%%%c\n" 3 -reg: ADDRLP4 "set %a,%%%c\nadd %%%c,%%fp,%%%c\n" 3 -con13: CNSTI1 "%a" imm(a) -con13: CNSTI2 "%a" imm(a) -con13: CNSTI4 "%a" imm(a) -con13: CNSTU1 "%a" imm(a) -con13: CNSTU2 "%a" imm(a) -con13: CNSTU4 "%a" imm(a) -con13: CNSTP4 "%a" imm(a) -base: ADDI4(reg,con13) "%%%0+%1" -base: ADDP4(reg,con13) "%%%0+%1" -base: ADDU4(reg,con13) "%%%0+%1" -base: reg "%%%0" -base: con13 "%0" -base: stk13 "%%fp+%0" -addr: base "%0" -addr: ADDI4(reg,reg) "%%%0+%%%1" -addr: ADDP4(reg,reg) "%%%0+%%%1" -addr: ADDU4(reg,reg) "%%%0+%%%1" -addr: stk "%%fp+%%%0" -reg: INDIRI1(addr) "ldsb [%0],%%%c\n" 1 -reg: INDIRI2(addr) "ldsh [%0],%%%c\n" 1 -reg: INDIRI4(addr) "ld [%0],%%%c\n" 1 -reg: INDIRU1(addr) "ldub [%0],%%%c\n" 1 -reg: INDIRU2(addr) "lduh [%0],%%%c\n" 1 -reg: INDIRU4(addr) "ld [%0],%%%c\n" 1 -reg: INDIRP4(addr) "ld [%0],%%%c\n" 1 -reg: INDIRF4(addr) "ld [%0],%%f%c\n" 1 -stmt: ASGNI1(addr,reg) "stb %%%1,[%0]\n" 1 -stmt: ASGNI2(addr,reg) "sth %%%1,[%0]\n" 1 -stmt: ASGNI4(addr,reg) "st %%%1,[%0]\n" 1 -stmt: ASGNU1(addr,reg) "stb %%%1,[%0]\n" 1 -stmt: ASGNU2(addr,reg) "sth %%%1,[%0]\n" 1 -stmt: ASGNU4(addr,reg) "st %%%1,[%0]\n" 1 -stmt: ASGNP4(addr,reg) "st %%%1,[%0]\n" 1 -stmt: ASGNF4(addr,reg) "st %%f%1,[%0]\n" 1 -addrl: ADDRLP4 "%%%fp+%a" imm(a) - -reg: INDIRF8(addrl) "ldd [%0],%%f%c\n" 1 -stmt: ASGNF8(addrl,reg) "std %%f%1,[%0]\n" 1 -reg: INDIRF8(base) "ld2 [%0],%%f%c\n" 2 -stmt: ASGNF8(base,reg) "st2 %%f%1,[%0]\n" 2 -spill: ADDRLP4 "%a" !imm(a) - -stmt: ASGNI1(spill,reg) "set %0,%%g1\nstb %%%1,[%%fp+%%g1]\n" -stmt: ASGNI2(spill,reg) "set %0,%%g1\nsth %%%1,[%%fp+%%g1]\n" -stmt: ASGNI4(spill,reg) "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n" -stmt: ASGNU1(spill,reg) "set %0,%%g1\nstb %%%1,[%%fp+%%g1]\n" -stmt: ASGNU2(spill,reg) "set %0,%%g1\nsth %%%1,[%%fp+%%g1]\n" -stmt: ASGNU4(spill,reg) "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n" -stmt: ASGNP4(spill,reg) "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n" -stmt: ASGNF4(spill,reg) "set %0,%%g1\nst %%f%1,[%%fp+%%g1]\n" -stmt: ASGNF8(spill,reg) "set %0,%%g1\nstd %%f%1,[%%fp+%%g1]\n" -reg: CVII4(INDIRI1(addr)) "ldsb [%0],%%%c\n" 1 -reg: CVII4(INDIRI2(addr)) "ldsh [%0],%%%c\n" 1 -reg: CVUU4(INDIRU1(addr)) "ldub [%0],%%%c\n" 1 -reg: CVUU4(INDIRU2(addr)) "lduh [%0],%%%c\n" 1 -reg: CVUI4(INDIRU1(addr)) "ldub [%0],%%%c\n" 1 -reg: CVUI4(INDIRU2(addr)) "lduh [%0],%%%c\n" 1 -reg: LOADI1(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADI2(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADI4(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADP4(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADU1(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADU2(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADU4(reg) "mov %%%0,%%%c\n" move(a) -reg: CNSTI1 "# reg\n" range(a, 0, 0) -reg: CNSTI2 "# reg\n" range(a, 0, 0) -reg: CNSTI4 "# reg\n" range(a, 0, 0) -reg: CNSTP4 "# reg\n" range(a, 0, 0) -reg: CNSTU1 "# reg\n" range(a, 0, 0) -reg: CNSTU2 "# reg\n" range(a, 0, 0) -reg: CNSTU4 "# reg\n" range(a, 0, 0) -reg: con "set %0,%%%c\n" 1 -rc: con13 "%0" -rc: reg "%%%0" -reg: ADDI4(reg,rc) "add %%%0,%1,%%%c\n" 1 -reg: ADDP4(reg,rc) "add %%%0,%1,%%%c\n" 1 -reg: ADDU4(reg,rc) "add %%%0,%1,%%%c\n" 1 -reg: BANDI4(reg,rc) "and %%%0,%1,%%%c\n" 1 -reg: BORI4(reg,rc) "or %%%0,%1,%%%c\n" 1 -reg: BXORI4(reg,rc) "xor %%%0,%1,%%%c\n" 1 -reg: BANDU4(reg,rc) "and %%%0,%1,%%%c\n" 1 -reg: BORU4(reg,rc) "or %%%0,%1,%%%c\n" 1 -reg: BXORU4(reg,rc) "xor %%%0,%1,%%%c\n" 1 -reg: SUBI4(reg,rc) "sub %%%0,%1,%%%c\n" 1 -reg: SUBP4(reg,rc) "sub %%%0,%1,%%%c\n" 1 -reg: SUBU4(reg,rc) "sub %%%0,%1,%%%c\n" 1 -rc5: CNSTI4 "%a" range(a, 0, 31) -rc5: reg "%%%0" -reg: LSHI4(reg,rc5) "sll %%%0,%1,%%%c\n" 1 -reg: LSHU4(reg,rc5) "sll %%%0,%1,%%%c\n" 1 -reg: RSHI4(reg,rc5) "sra %%%0,%1,%%%c\n" 1 -reg: RSHU4(reg,rc5) "srl %%%0,%1,%%%c\n" 1 -reg: BANDI4(reg,BCOMI4(rc)) "andn %%%0,%1,%%%c\n" 1 -reg: BORI4(reg,BCOMI4(rc)) "orn %%%0,%1,%%%c\n" 1 -reg: BXORI4(reg,BCOMI4(rc)) "xnor %%%0,%1,%%%c\n" 1 -reg: BANDU4(reg,BCOMU4(rc)) "andn %%%0,%1,%%%c\n" 1 -reg: BORU4(reg,BCOMU4(rc)) "orn %%%0,%1,%%%c\n" 1 -reg: BXORU4(reg,BCOMU4(rc)) "xnor %%%0,%1,%%%c\n" 1 -reg: NEGI4(reg) "neg %%%0,%%%c\n" 1 -reg: BCOMI4(reg) "not %%%0,%%%c\n" 1 -reg: BCOMU4(reg) "not %%%0,%%%c\n" 1 -reg: CVII4(reg) "sll %%%0,8*(4-%a),%%%c; sra %%%c,8*(4-%a),%%%c\n" 2 -reg: CVUU4(reg) "sll %%%0,8*(4-%a),%%%c; srl %%%c,8*(4-%a),%%%c\n" 2 -reg: CVUU4(reg) "and %%%0,0xff,%%%c\n" (a->syms[0]->u.c.v.i == 1 ? 1 : LBURG_MAX) -reg: CVUU4(reg) "set 0xffff,%%g1; and %%%0,%%g1,%%%c\n" 2 -reg: CVUI4(reg) "and %%%0,0xff,%%%c\n" (a->syms[0]->u.c.v.i == 1 ? 1 : LBURG_MAX) -reg: CVUI4(reg) "set 0xffff,%%g1; and %%%0,%%g1,%%%c\n" 2 -addrg: ADDRGP4 "%a" -stmt: JUMPV(addrg) "ba %0; nop\n" 2 -stmt: JUMPV(addr) "jmp %0; nop\n" 2 -stmt: LABELV "%a:\n" -stmt: EQI4(reg,rc) "cmp %%%0,%1; be %a; nop\n" 3 -stmt: EQU4(reg,rc) "cmp %%%0,%1; be %a; nop\n" 3 -stmt: GEI4(reg,rc) "cmp %%%0,%1; bge %a; nop\n" 3 -stmt: GEU4(reg,rc) "cmp %%%0,%1; bgeu %a; nop\n" 3 -stmt: GTI4(reg,rc) "cmp %%%0,%1; bg %a; nop\n" 3 -stmt: GTU4(reg,rc) "cmp %%%0,%1; bgu %a; nop\n" 3 -stmt: LEI4(reg,rc) "cmp %%%0,%1; ble %a; nop\n" 3 -stmt: LEU4(reg,rc) "cmp %%%0,%1; bleu %a; nop\n" 3 -stmt: LTI4(reg,rc) "cmp %%%0,%1; bl %a; nop\n" 3 -stmt: LTU4(reg,rc) "cmp %%%0,%1; blu %a; nop\n" 3 -stmt: NEI4(reg,rc) "cmp %%%0,%1; bne %a; nop\n" 3 -stmt: NEU4(reg,rc) "cmp %%%0,%1; bne %a; nop\n" 3 -call: ADDRGP4 "%a" -call: addr "%0" -reg: CALLF8(call) "call %0; nop\n" 2 -reg: CALLF4(call) "call %0; nop\n" 2 -reg: CALLI4(call) "call %0; nop\n" 2 -reg: CALLP4(call) "call %0; nop\n" 2 -reg: CALLU4(call) "call %0; nop\n" 2 -stmt: CALLV(call) "call %0; nop\n" 2 -stmt: CALLB(call,reg) "call %0; st %%%1,[%%sp+64]; unimp %b&0xfff\n" 3 - -stmt: RETF8(reg) "# ret\n" 1 -stmt: RETF4(reg) "# ret\n" 1 -stmt: RETI4(reg) "# ret\n" 1 -stmt: RETU4(reg) "# ret\n" 1 -stmt: RETP4(reg) "# ret\n" 1 -stmt: ARGI4(reg) "st %%%0,[%%sp+4*%c+68]\n" 1 -stmt: ARGU4(reg) "st %%%0,[%%sp+4*%c+68]\n" 1 -stmt: ARGP4(reg) "st %%%0,[%%sp+4*%c+68]\n" 1 -stmt: ARGF4(reg) "# ARGF4\n" 1 -stmt: ARGF8(reg) "# ARGF8\n" 1 - -reg: DIVI4(reg,rc) "sra %%%0,31,%%g1; wr %%g0,%%g1,%%y; nop; nop; nop; sdiv %%%0,%1,%%%c\n" 6 - -reg: DIVU4(reg,rc) "wr %%g0,%%g0,%%y; nop; nop; nop; udiv %%%0,%1,%%%c\n" 5 - -reg: MODI4(reg,rc) "sra %%%0,31,%%g1; wr %%g0,%%g1,%%y; nop; nop; nop; sdiv %%%0,%1,%%g1\n; smul %%g1,%1,%%g1; sub %%%0,%%g1,%%%c\n" 8 - - -reg: MODU4(reg,rc) "wr %%g0,%%g0,%%y; nop; nop; nop; udiv %%%0,%1,%%g1\n; umul %%g1,%1,%%g1; sub %%%0,%%g1,%%%c\n" 7 - - -reg: MULI4(rc,reg) "smul %%%1,%0,%%%c\n" 1 -reg: MULU4(rc,reg) "umul %%%1,%0,%%%c\n" 1 -reg: ADDF8(reg,reg) "faddd %%f%0,%%f%1,%%f%c\n" 1 -reg: ADDF4(reg,reg) "fadds %%f%0,%%f%1,%%f%c\n" 1 -reg: DIVF8(reg,reg) "fdivd %%f%0,%%f%1,%%f%c\n" 1 -reg: DIVF4(reg,reg) "fdivs %%f%0,%%f%1,%%f%c\n" 1 -reg: MULF8(reg,reg) "fmuld %%f%0,%%f%1,%%f%c\n" 1 -reg: MULF4(reg,reg) "fmuls %%f%0,%%f%1,%%f%c\n" 1 -reg: SUBF8(reg,reg) "fsubd %%f%0,%%f%1,%%f%c\n" 1 -reg: SUBF4(reg,reg) "fsubs %%f%0,%%f%1,%%f%c\n" 1 -reg: NEGF4(reg) "fnegs %%f%0,%%f%c\n" 1 -reg: LOADF4(reg) "fmovs %%f%0,%%f%c\n" 1 -reg: CVFF4(reg) "fdtos %%f%0,%%f%c\n" 1 -reg: CVFF8(reg) "fstod %%f%0,%%f%c\n" 1 -reg: CVFI4(reg) "fstoi %%f%0,%%f0; st %%f0,[%%sp+64]; ld [%%sp+64],%%%c\n" (a->syms[0]->u.c.v.i==4?3:LBURG_MAX) - -reg: CVFI4(reg) "fdtoi %%f%0,%%f0; st %%f0,[%%sp+64]; ld [%%sp+64],%%%c\n" (a->syms[0]->u.c.v.i==8?3:LBURG_MAX) - -reg: CVIF4(reg) "st %%%0,[%%sp+64]; ld [%%sp+64],%%f%c; fitos %%f%c,%%f%c\n" 3 - -reg: CVIF8(reg) "st %%%0,[%%sp+64]; ld [%%sp+64],%%f%c; fitod %%f%c,%%f%c\n" 3 - -rel: EQF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbue" -rel: EQF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbue" -rel: GEF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbuge" -rel: GEF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbuge" -rel: GTF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbug" -rel: GTF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbug" -rel: LEF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbule" -rel: LEF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbule" -rel: LTF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbul" -rel: LTF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbul" -rel: NEF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbne" -rel: NEF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbne" - -stmt: rel "%0 %a; nop\n" 4 -reg: LOADF8(reg) "# LOADD\n" 2 - -reg: NEGF8(reg) "# NEGD\n" 2 - -stmt: ASGNB(reg,INDIRB(reg)) "# ASGNB\n" - -%% -static void progend(void){} -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - parseflags(argc, argv); - for (i = 0; i < argc; i++) - if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-pg") == 0) - pflag = 1; - if (IR == &solarisIR) - stabprefix = ".LL"; - else - stabprefix = "L"; - for (i = 0; i < 8; i++) { - greg[i + 0] = mkreg(stringf("g%d", i), i + 0, 1, IREG); - greg[i + 8] = mkreg(stringf("o%d", i), i + 8, 1, IREG); - greg[i + 16] = mkreg(stringf("l%d", i), i + 16, 1, IREG); - greg[i + 24] = mkreg(stringf("i%d", i), i + 24, 1, IREG); - } - gregw = mkwildcard(greg); - for (i = 0; i < 32; i++) - freg[i] = mkreg("%d", i, 1, FREG); - for (i = 0; i < 31; i += 2) - freg2[i] = mkreg("%d", i, 3, FREG); - fregw = mkwildcard(freg); - freg2w = mkwildcard(freg2); - tmask[IREG] = 0x3fff3e00; - vmask[IREG] = 0x3ff00000; - tmask[FREG] = ~(unsigned)0; - vmask[FREG] = 0; -} -static Symbol rmap(int opk) { - switch (optype(opk)) { - case I: case U: case P: case B: - return gregw; - case F: - return opsize(opk) == 4 ? fregw : freg2w; - default: - return 0; - } -} -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case CNST+I: case CNST+U: case CNST+P: - if (range(p, 0, 0) == 0) { - setreg(p, greg[0]); - p->x.registered = 1; - } - break; - case CALL+B: - assert(p->syms[1] && p->syms[1]->type && isfunc(p->syms[1]->type)); - p->syms[1] = intconst(freturn(p->syms[1]->type)->size); - break; - case CALL+F: setreg(p, opsize(p->op)==4?freg[0]:freg2[0]); break; - case CALL+I: case CALL+P: case CALL+U: - case CALL+V: setreg(p, oreg[0]); break; - case RET+F: rtarget(p, 0, opsize(p->op)==4?freg[0]:freg2[0]); break; - case RET+I: case RET+P: case RET+U: - rtarget(p, 0, ireg[0]); - p->kids[0]->x.registered = 1; - break; - case ARG+I: case ARG+P: case ARG+U: - if (p->syms[RX]->u.c.v.i < 6) { - rtarget(p, 0, oreg[p->syms[RX]->u.c.v.i]); - p->op = LOAD+opkind(p->op); - setreg(p, oreg[p->syms[RX]->u.c.v.i]); - } - break; - } -} -static void clobber(Node p) { - assert(p); - switch (specific(p->op)) { - case CALL+B: case CALL+F: case CALL+I: - spill(~(unsigned)3, FREG, p); - break; - case CALL+V: - spill(oreg[0]->x.regnode->mask, IREG, p); - spill(~(unsigned)3, FREG, p); - break; - case ARG+F: - if (opsize(p->op) == 4 && p->syms[2]->u.c.v.i <= 6) - spill((1<<(p->syms[2]->u.c.v.i + 8)), IREG, p); - else if (opsize(p->op) == 8 && p->syms[2]->u.c.v.i <= 5) - spill((3<<(p->syms[2]->u.c.v.i + 8))&0xff00, IREG, p); - break; - } -} -static int imm(Node p) { - return range(p, -4096, 4091); -} -static void doarg(Node p) { - assert(p && p->syms[0] && p->op != ARG+B); - p->syms[RX] = intconst(mkactual(4, - p->syms[0]->u.c.v.i)/4); -} -static void emit2(Node p) { - switch (p->op) { - case ARG+F+sizeop(4): { - int n = p->syms[RX]->u.c.v.i; - print("st %%f%d,[%%sp+4*%d+68]\n", - getregnum(p->x.kids[0]), n); - if (n <= 5) - print("ld [%%sp+4*%d+68],%%o%d\n", n, n); - break; - } - case ARG+F+sizeop(8): { - int n = p->syms[RX]->u.c.v.i; - int src = getregnum(p->x.kids[0]); - print("st %%f%d,[%%sp+4*%d+68]\n", src, n); - print("st %%f%d,[%%sp+4*%d+68]\n", src+1, n+1); - if (n <= 5) - print("ld [%%sp+4*%d+68],%%o%d\n", n, n); - if (n <= 4) - print("ld [%%sp+4*%d+68],%%o%d\n", n+1, n+1); - break; - } - case LOAD+F+sizeop(8): { - int dst = getregnum(p); - int src = getregnum(p->x.kids[0]); - print("fmovs %%f%d,%%f%d; ", src, dst); - print("fmovs %%f%d,%%f%d\n", src+1, dst+1); - break; - } - case NEG+F+sizeop(8): { - int dst = getregnum(p); - int src = getregnum(p->x.kids[0]); - print("fnegs %%f%d,%%f%d; ", src, dst); - print("fmovs %%f%d,%%f%d\n", src+1, dst+1); - break; - } - case ASGN+B: { - static int tmpregs[] = { 1, 2, 3 }; - dalign = salign = p->syms[1]->u.c.v.i; - blkcopy(getregnum(p->x.kids[0]), 0, - getregnum(p->x.kids[1]), 0, - p->syms[0]->u.c.v.i, tmpregs); - break; - } - } -} -static void local(Symbol p) { - if (retstruct) { - assert(p == retv); - p->x.name = stringd(4*16); - p->x.offset = 4*16; - p->sclass = AUTO; - retstruct = 0; - return; - } - if (isscalar(p->type) && !p->addressed && !isfloat(p->type)) - p->sclass = REGISTER; - if (askregvar(p, rmap(ttob(p->type))) == 0) - mkauto(p); - else if (p->scope > LOCAL) - regvars++; -} -static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - int autos = 0, i, leaf, reg, varargs; - - if (IR == &solarisIR) - globalend(); - regvars = 0; - for (i = 0; callee[i]; i++) - ; - varargs = variadic(f->type) - || i > 0 && strcmp(callee[i-1]->name, - "__builtin_va_alist") == 0; - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~(unsigned)0; - for (i = 0; i < 8; i++) - ireg[i]->x.regnode->vbl = NULL; - offset = 68; - maxargoffset = 24; - reg = 0; - for (i = 0; callee[i]; i++) { - Symbol p = callee[i], q = caller[i]; - int size = roundup(q->type->size, 4); - assert(q); - if (isfloat(p->type) || reg >= 6) { - p->x.offset = q->x.offset = offset; - p->x.name = q->x.name = stringd(offset); - p->sclass = q->sclass = AUTO; - autos++; - } - else if (p->addressed || varargs) { - p->x.offset = offset; - p->x.name = stringd(p->x.offset); - p->sclass = AUTO; - q->sclass = REGISTER; - askregvar(q, ireg[reg]); - assert(q->x.regnode); - autos++; - } - else { - p->sclass = q->sclass = REGISTER; - askregvar(p, ireg[reg]); - assert(p->x.regnode); - q->x.name = p->x.name; - } - offset += size; - reg += isstruct(p->type) ? 1 : size/4; - } - assert(caller[i] == 0); - offset = maxoffset = 0; - retstruct = isstruct(freturn(f->type)); - gencode(caller, callee); - maxargoffset = roundup(maxargoffset, 4); - framesize = roundup(maxoffset + maxargoffset + 4*(16+1), 8); - assert(!varargs || autos); - leaf = (!ncalls - && !maxoffset && !autos && !regvars - && !isstruct(freturn(f->type)) - && !(usedmask[IREG]&0x00ffff01) - && !(usedmask[FREG]&~(unsigned)3) - && !pflag && !glevel); - print(".align 4\n%s:\n", f->x.name); - if (leaf) { - for (i = 0; caller[i] && callee[i]; i++) { - Symbol p = caller[i], q = callee[i]; - if (p->sclass == REGISTER && q->sclass == REGISTER) { - assert(q->x.regnode); - assert(q->x.regnode->set == IREG); - assert(q->x.regnode->number >= 24); - assert(q->x.regnode->number <= 31); - p->x.name = greg[q->x.regnode->number - 16]->x.name; - } - } - renameregs(); - } else if (framesize <= 4095) - print("save %%sp,%d,%%sp\n", -framesize); - else - print("set %d,%%g1; save %%sp,%%g1,%%sp\n", -framesize); - if (varargs) - for (; reg < 6; reg++) - print("st %%i%d,[%%fp+%d]\n", reg, 4*reg + 68); - else { - offset = 4*(16 + 1); - reg = 0; - for (i = 0; caller[i]; i++) { - Symbol p = caller[i]; - if (isfloat(p->type) && p->type->size == 8 && reg <= 4) { - print("st %%r%d,[%%fp+%d]\n", - ireg[reg++]->x.regnode->number, offset); - print("st %%r%d,[%%fp+%d]\n", - ireg[reg++]->x.regnode->number, offset + 4); - } else if (isfloat(p->type) && p->type->size == 4 && reg <= 5) - print("st %%r%d,[%%fp+%d]\n", - ireg[reg++]->x.regnode->number, offset); - else - reg++; - offset += roundup(p->type->size, 4); - } - } - if (pflag) { - int lab = genlabel(1); - print("set L%d,%%o0; call mcount; nop\n", lab); - print(".seg \"data\"\n.align 4; L%d:.word 0\n.seg \"text\"\n", lab); - } - emitcode(); - if (isstruct(freturn(f->type))) - print("jmp %%i7+12; restore\n"); - else if (!leaf) - print("ret; restore\n"); - else { - renameregs(); - print("retl; nop\n"); - } - if (IR == &solarisIR) { - print(".type %s,#function\n", f->x.name); - print(".size %s,.-%s\n", f->x.name, f->x.name); - } -} -#define exch(x, y, t) (((t) = x), ((x) = (y)), ((y) = (t))) - -static void renameregs(void) { - int i; - - for (i = 0; i < 8; i++) { - char *ptmp; - int itmp; - if (ireg[i]->x.regnode->vbl) - ireg[i]->x.regnode->vbl->x.name = oreg[i]->x.name; - exch(ireg[i]->x.name, oreg[i]->x.name, ptmp); - exch(ireg[i]->x.regnode->number, - oreg[i]->x.regnode->number, itmp); - } -} -static void defconst(int suffix, int size, Value v) { - if (suffix == F && size == 4) { - float f = v.d; - print(".word 0x%x\n", *(unsigned *)&f); - } else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print(".word 0x%x\n.word 0x%x\n", p[swap], p[!swap]); - } else if (suffix == P) - print(".word 0x%x\n", v.p); - else if (size == 1) - print(".byte 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 2) - print(".half 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 4) - print(".word 0x%x\n", suffix == I ? v.i : v.u); - else assert(0); -} - -static void defaddress(Symbol p) { - print(".word %s\n", p->x.name); -} - -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print(".byte %d\n", (*s)&0377); -} - -static void address(Symbol q, Symbol p, long n) { - if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) - q->x.name = stringf("%s%s%D", p->x.name, n >= 0 ? "+" : "", n); - else { - assert(n <= INT_MAX && n >= INT_MIN); - q->x.offset = p->x.offset + n; - q->x.name = stringd(q->x.offset); - } -} -static void export(Symbol p) { - print(".global %s\n", p->x.name); -} -static void import(Symbol p) {} -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("%d", genlabel(1)); - else - assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), - p->x.name = p->name; - if (p->scope >= LABELS) - p->x.name = stringf(p->generated ? "L%s" : "_%s", - p->x.name); -} -static void segment(int n) { - cseg = n; - switch (n) { - case CODE: print(".seg \"text\"\n"); break; - case BSS: print(".seg \"bss\"\n"); break; - case DATA: print(".seg \"data\"\n"); break; - case LIT: print(".seg \"text\"\n"); break; - } -} -static void space(int n) { - if (cseg != BSS) - print(".skip %d\n", n); -} -static void global(Symbol p) { - print(".align %d\n", p->type->align); - assert(p->u.seg); - if (p->u.seg == BSS - && (p->sclass == STATIC || Aflag >= 2)) - print(".reserve %s,%d\n", p->x.name, p->type->size); - else if (p->u.seg == BSS) - print(".common %s,%d\n", p->x.name, p->type->size); - else - print("%s:\n", p->x.name); -} -static void blkfetch(int k, int off, int reg, int tmp) { - assert(k == 1 || k == 2 || k == 4); - assert(salign >= k); - if (k == 1) - print("ldub [%%r%d+%d],%%r%d\n", reg, off, tmp); - else if (k == 2) - print("lduh [%%r%d+%d],%%r%d\n", reg, off, tmp); - else - print("ld [%%r%d+%d],%%r%d\n", reg, off, tmp); -} -static void blkstore(int k, int off, int reg, int tmp) { - assert(k == 1 || k == 2 || k == 4); - assert(dalign >= k); - if (k == 1) - print("stb %%r%d,[%%r%d+%d]\n", tmp, reg, off); - else if (k == 2) - print("sth %%r%d,[%%r%d+%d]\n", tmp, reg, off); - else - print("st %%r%d,[%%r%d+%d]\n", tmp, reg, off); -} -static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) { - if ((size&~7) < 4096) { - print("add %%r%d,%d,%%r%d\n", sreg, size&~7, sreg); - print("add %%r%d,%d,%%r%d\n", dreg, size&~7, tmps[2]); - } else { - print("set %d,%%r%d\n", size&~7, tmps[2]); - print("add %%r%d,%%r%d,%%r%d\n", sreg, tmps[2], sreg); - print("add %%r%d,%%r%d,%%r%d\n", dreg, tmps[2], tmps[2]); - } - blkcopy(tmps[2], doff, sreg, soff, size&7, tmps); - print("1: dec 8,%%r%d\n", tmps[2]); - blkcopy(tmps[2], doff, sreg, soff - 8, 8, tmps); - print("cmp %%r%d,%%r%d; ", tmps[2], dreg); - print("bgt 1b; "); - print("dec 8,%%r%d\n", sreg); -} -static void defsymbol2(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf(".%d", genlabel(1)); - else - assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), - p->x.name = p->name; - if (p->scope >= LABELS) - p->x.name = stringf(p->generated ? ".L%s" : "%s", - p->x.name); -} - -static Symbol prevg; - -static void globalend(void) { - if (prevg && prevg->type->size > 0) - print(".size %s,%d\n", prevg->x.name, prevg->type->size); - prevg = NULL; -} - -static void export2(Symbol p) { - globalend(); - print(".global %s\n", p->x.name); -} - -static void progend2(void) { - globalend(); -} - -static void global2(Symbol p) { - globalend(); - assert(p->u.seg); - if (!p->generated) { - print(".type %s,#%s\n", p->x.name, - isfunc(p->type) ? "function" : "object"); - if (p->type->size > 0) - print(".size %s,%d\n", p->x.name, p->type->size); - else - prevg = p; - } - if (p->u.seg == BSS && p->sclass == STATIC) - print(".local %s\n.common %s,%d,%d\n", p->x.name, p->x.name, - p->type->size, p->type->align); - else if (p->u.seg == BSS && Aflag >= 2) - print(".align %d\n%s:.skip %d\n", p->type->align, p->x.name, - p->type->size); - else if (p->u.seg == BSS) - print(".common %s,%d,%d\n", p->x.name, p->type->size, p->type->align); - else - print(".align %d\n%s:\n", p->type->align, p->x.name); -} - -static void segment2(int n) { - cseg = n; - switch (n) { - case CODE: print(".section \".text\"\n"); break; - case BSS: print(".section \".bss\"\n"); break; - case DATA: print(".section \".data\"\n"); break; - case LIT: print(".section \".rodata\"\n"); break; - } -} -Interface sparcIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 1, 0, /* struct */ - 0, /* little_endian */ - 0, /* mulops_calls */ - 1, /* wants_callb */ - 0, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - stabblock, 0, 0, stabinit, stabline, stabsym, stabtype, - { - 1, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } -}; - -Interface solarisIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 1, 0, /* struct */ - 0, /* little_endian */ - 0, /* mulops_calls */ - 1, /* wants_callb */ - 0, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol2, - emit, - export2, - function, - gen, - global2, - import, - local, - progbeg, - progend2, - segment2, - space, - stabblock, 0, 0, stabinit, stabline, stabsym, stabtype, - { - 1, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } -}; -static char rcsid[] = "$Id: sparc.md 145 2001-10-17 21:53:10Z timo $"; diff --git a/code/tools/lcc/src/x86.md b/code/tools/lcc/src/x86.md deleted file mode 100644 index 6c4e1c4..0000000 --- a/code/tools/lcc/src/x86.md +++ /dev/null @@ -1,998 +0,0 @@ -%{ -enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 }; -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -static void address(Symbol, Symbol, long); -static void blkfetch(int, int, int, int); -static void blkloop(int, int, int, int, int, int[]); -static void blkstore(int, int, int, int); -static void defaddress(Symbol); -static void defconst(int, int, Value); -static void defstring(int, char *); -static void defsymbol(Symbol); -static void doarg(Node); -static void emit2(Node); -static void export(Symbol); -static void clobber(Node); -static void function(Symbol, Symbol [], Symbol [], int); -static void global(Symbol); -static void import(Symbol); -static void local(Symbol); -static void progbeg(int, char **); -static void progend(void); -static void segment(int); -static void space(int); -static void target(Node); -extern int ckstack(Node, int); -extern int memop(Node); -extern int sametree(Node, Node); -static Symbol charreg[32], shortreg[32], intreg[32]; -static Symbol fltreg[32]; - -static Symbol charregw, shortregw, intregw, fltregw; - -static int cseg; - -static Symbol quo, rem; - -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRF4(VREGP) "# read register\n" -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRF8(VREGP) "# read register\n" -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" -con: CNSTI1 "%a" -con: CNSTU1 "%a" - -con: CNSTI2 "%a" -con: CNSTU2 "%a" - -con: CNSTI4 "%a" -con: CNSTU4 "%a" -con: CNSTP4 "%a" - -con: CNSTI8 "%a" -con: CNSTU8 "%a" -con: CNSTP8 "%a" -stmt: reg "" -acon: ADDRGP4 "(%a)" -acon: con "(%0)" -base: ADDRGP4 "(%a)" -base: reg "[%0]" -base: ADDI4(reg,acon) "%1[%0]" -base: ADDP4(reg,acon) "%1[%0]" -base: ADDU4(reg,acon) "%1[%0]" -base: ADDRFP4 "(%a)[ebp]" -base: ADDRLP4 "(%a)[ebp]" -index: reg "%0" -index: LSHI4(reg,con1) "%0*2" -index: LSHI4(reg,con2) "%0*4" -index: LSHI4(reg,con3) "%0*8" - -con1: CNSTI4 "1" range(a, 1, 1) -con1: CNSTU4 "1" range(a, 1, 1) -con2: CNSTI4 "2" range(a, 2, 2) -con2: CNSTU4 "2" range(a, 2, 2) -con3: CNSTI4 "3" range(a, 3, 3) -con3: CNSTU4 "3" range(a, 3, 3) -index: LSHU4(reg,con1) "%0*2" -index: LSHU4(reg,con2) "%0*4" -index: LSHU4(reg,con3) "%0*8" -addr: base "%0" -addr: ADDI4(index,base) "%1[%0]" -addr: ADDP4(index,base) "%1[%0]" -addr: ADDU4(index,base) "%1[%0]" -addr: index "[%0]" -mem: INDIRI1(addr) "byte ptr %0" -mem: INDIRI2(addr) "word ptr %0" -mem: INDIRI4(addr) "dword ptr %0" -mem: INDIRU1(addr) "byte ptr %0" -mem: INDIRU2(addr) "word ptr %0" -mem: INDIRU4(addr) "dword ptr %0" -mem: INDIRP4(addr) "dword ptr %0" -rc: reg "%0" -rc: con "%0" - -mr: reg "%0" -mr: mem "%0" - -mrc0: mem "%0" -mrc0: rc "%0" -mrc1: mem "%0" 1 -mrc1: rc "%0" - -mrc3: mem "%0" 3 -mrc3: rc "%0" -reg: addr "lea %c,%0\n" 1 -reg: mrc0 "mov %c,%0\n" 1 -reg: LOADI1(reg) "# move\n" 1 -reg: LOADI2(reg) "# move\n" 1 -reg: LOADI4(reg) "# move\n" move(a) -reg: LOADU1(reg) "# move\n" 1 -reg: LOADU2(reg) "# move\n" 1 -reg: LOADU4(reg) "# move\n" move(a) -reg: LOADP4(reg) "# move\n" move(a) -reg: ADDI4(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1 -reg: ADDP4(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1 -reg: ADDU4(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1 -reg: SUBI4(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1 -reg: SUBP4(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1 -reg: SUBU4(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1 -reg: BANDI4(reg,mrc1) "?mov %c,%0\nand %c,%1\n" 1 -reg: BORI4(reg,mrc1) "?mov %c,%0\nor %c,%1\n" 1 -reg: BXORI4(reg,mrc1) "?mov %c,%0\nxor %c,%1\n" 1 -reg: BANDU4(reg,mrc1) "?mov %c,%0\nand %c,%1\n" 1 -reg: BORU4(reg,mrc1) "?mov %c,%0\nor %c,%1\n" 1 -reg: BXORU4(reg,mrc1) "?mov %c,%0\nxor %c,%1\n" 1 -stmt: ASGNI4(addr,ADDI4(mem,con1)) "inc %1\n" memop(a) -stmt: ASGNI4(addr,ADDU4(mem,con1)) "inc %1\n" memop(a) -stmt: ASGNP4(addr,ADDP4(mem,con1)) "inc %1\n" memop(a) -stmt: ASGNI4(addr,SUBI4(mem,con1)) "dec %1\n" memop(a) -stmt: ASGNI4(addr,SUBU4(mem,con1)) "dec %1\n" memop(a) -stmt: ASGNP4(addr,SUBP4(mem,con1)) "dec %1\n" memop(a) -stmt: ASGNI4(addr,ADDI4(mem,rc)) "add %1,%2\n" memop(a) -stmt: ASGNI4(addr,SUBI4(mem,rc)) "sub %1,%2\n" memop(a) -stmt: ASGNU4(addr,ADDU4(mem,rc)) "add %1,%2\n" memop(a) -stmt: ASGNU4(addr,SUBU4(mem,rc)) "sub %1,%2\n" memop(a) - -stmt: ASGNI4(addr,BANDI4(mem,rc)) "and %1,%2\n" memop(a) -stmt: ASGNI4(addr,BORI4(mem,rc)) "or %1,%2\n" memop(a) -stmt: ASGNI4(addr,BXORI4(mem,rc)) "xor %1,%2\n" memop(a) -stmt: ASGNU4(addr,BANDU4(mem,rc)) "and %1,%2\n" memop(a) -stmt: ASGNU4(addr,BORU4(mem,rc)) "or %1,%2\n" memop(a) -stmt: ASGNU4(addr,BXORU4(mem,rc)) "xor %1,%2\n" memop(a) -reg: BCOMI4(reg) "?mov %c,%0\nnot %c\n" 2 -reg: BCOMU4(reg) "?mov %c,%0\nnot %c\n" 2 -reg: NEGI4(reg) "?mov %c,%0\nneg %c\n" 2 - -stmt: ASGNI4(addr,BCOMI4(mem)) "not %1\n" memop(a) -stmt: ASGNU4(addr,BCOMU4(mem)) "not %1\n" memop(a) -stmt: ASGNI4(addr,NEGI4(mem)) "neg %1\n" memop(a) -reg: LSHI4(reg,con5) "?mov %c,%0\nsal %c,%1\n" 2 -reg: LSHU4(reg,con5) "?mov %c,%0\nshl %c,%1\n" 2 -reg: RSHI4(reg,con5) "?mov %c,%0\nsar %c,%1\n" 2 -reg: RSHU4(reg,con5) "?mov %c,%0\nshr %c,%1\n" 2 - -stmt: ASGNI4(addr,LSHI4(mem,con5)) "sal %1,%2\n" memop(a) -stmt: ASGNI4(addr,LSHU4(mem,con5)) "shl %1,%2\n" memop(a) -stmt: ASGNI4(addr,RSHI4(mem,con5)) "sar %1,%2\n" memop(a) -stmt: ASGNI4(addr,RSHU4(mem,con5)) "shr %1,%2\n" memop(a) - -con5: CNSTI4 "%a" range(a, 0, 31) - -reg: LSHI4(reg,reg) "?mov %c,%0\nmov ecx,%1\nsal %c,cl\n" 3 -reg: LSHU4(reg,reg) "?mov %c,%0\nmov ecx,%1\nshl %c,cl\n" 2 -reg: RSHI4(reg,reg) "?mov %c,%0\nmov ecx,%1\nsar %c,cl\n" 2 -reg: RSHU4(reg,reg) "?mov %c,%0\nmov ecx,%1\nshr %c,cl\n" 2 -reg: MULI4(reg,mrc3) "?mov %c,%0\nimul %c,%1\n" 14 -reg: MULI4(con,mr) "imul %c,%1,%0\n" 13 -reg: MULU4(reg,mr) "mul %1\n" 13 -reg: DIVU4(reg,reg) "xor edx,edx\ndiv %1\n" -reg: MODU4(reg,reg) "xor edx,edx\ndiv %1\n" -reg: DIVI4(reg,reg) "cdq\nidiv %1\n" -reg: MODI4(reg,reg) "cdq\nidiv %1\n" -reg: CVPU4(reg) "mov %c,%0\n" move(a) -reg: CVUP4(reg) "mov %c,%0\n" move(a) -reg: CVII4(INDIRI1(addr)) "movsx %c,byte ptr %0\n" 3 -reg: CVII4(INDIRI2(addr)) "movsx %c,word ptr %0\n" 3 -reg: CVUU4(INDIRU1(addr)) "movzx %c,byte ptr %0\n" 3 -reg: CVUU4(INDIRU2(addr)) "movzx %c,word ptr %0\n" 3 -reg: CVII4(reg) "# extend\n" 3 -reg: CVIU4(reg) "# extend\n" 3 -reg: CVUI4(reg) "# extend\n" 3 -reg: CVUU4(reg) "# extend\n" 3 - -reg: CVII1(reg) "# truncate\n" 1 -reg: CVII2(reg) "# truncate\n" 1 -reg: CVUU1(reg) "# truncate\n" 1 -reg: CVUU2(reg) "# truncate\n" 1 -stmt: ASGNI1(addr,rc) "mov byte ptr %0,%1\n" 1 -stmt: ASGNI2(addr,rc) "mov word ptr %0,%1\n" 1 -stmt: ASGNI4(addr,rc) "mov dword ptr %0,%1\n" 1 -stmt: ASGNU1(addr,rc) "mov byte ptr %0,%1\n" 1 -stmt: ASGNU2(addr,rc) "mov word ptr %0,%1\n" 1 -stmt: ASGNU4(addr,rc) "mov dword ptr %0,%1\n" 1 -stmt: ASGNP4(addr,rc) "mov dword ptr %0,%1\n" 1 -stmt: ARGI4(mrc3) "push %0\n" 1 -stmt: ARGU4(mrc3) "push %0\n" 1 -stmt: ARGP4(mrc3) "push %0\n" 1 -stmt: ASGNB(reg,INDIRB(reg)) "mov ecx,%a\nrep movsb\n" -stmt: ARGB(INDIRB(reg)) "sub esp,%a\nmov edi,esp\nmov ecx,%a\nrep movsb\n" - -memf: INDIRF8(addr) "qword ptr %0" -memf: INDIRF4(addr) "dword ptr %0" -memf: CVFF8(INDIRF4(addr)) "dword ptr %0" -reg: memf "fld %0\n" 3 -stmt: ASGNF8(addr,reg) "fstp qword ptr %0\n" 7 -stmt: ASGNF4(addr,reg) "fstp dword ptr %0\n" 7 -stmt: ASGNF4(addr,CVFF4(reg)) "fstp dword ptr %0\n" 7 -stmt: ARGF8(reg) "sub esp,8\nfstp qword ptr [esp]\n" -stmt: ARGF4(reg) "sub esp,4\nfstp dword ptr [esp]\n" -reg: NEGF8(reg) "fchs\n" -reg: NEGF4(reg) "fchs\n" -flt: memf " %0" -flt: reg "p st(1),st" -reg: ADDF8(reg,flt) "fadd%1\n" -reg: ADDF4(reg,flt) "fadd%1\n" -reg: DIVF8(reg,flt) "fdiv%1\n" -reg: DIVF4(reg,flt) "fdiv%1\n" -reg: MULF8(reg,flt) "fmul%1\n" -reg: MULF4(reg,flt) "fmul%1\n" -reg: SUBF8(reg,flt) "fsub%1\n" -reg: SUBF4(reg,flt) "fsub%1\n" -reg: CVFF8(reg) "# CVFF8\n" -reg: CVFF4(reg) "sub esp,4\nfstp dword ptr 0[esp]\nfld dword ptr 0[esp]\nadd esp,4\n" 12 - -reg: CVFI4(reg) "call __ftol\n" 31 -reg: CVIF8(INDIRI4(addr)) "fild dword ptr %0\n" 10 -reg: CVIF4(reg) "push %0\nfild dword ptr 0[esp]\nadd esp,4\n" 12 - -reg: CVIF8(reg) "push %0\nfild dword ptr 0[esp]\nadd esp,4\n" 12 - -addrj: ADDRGP4 "%a" -addrj: reg "%0" 2 -addrj: mem "%0" 2 - -stmt: JUMPV(addrj) "jmp %0\n" 3 -stmt: LABELV "%a:\n" -stmt: EQI4(mem,rc) "cmp %0,%1\nje %a\n" 5 -stmt: GEI4(mem,rc) "cmp %0,%1\njge %a\n" 5 -stmt: GTI4(mem,rc) "cmp %0,%1\njg %a\n" 5 -stmt: LEI4(mem,rc) "cmp %0,%1\njle %a\n" 5 -stmt: LTI4(mem,rc) "cmp %0,%1\njl %a\n" 5 -stmt: NEI4(mem,rc) "cmp %0,%1\njne %a\n" 5 -stmt: GEU4(mem,rc) "cmp %0,%1\njae %a\n" 5 -stmt: GTU4(mem,rc) "cmp %0,%1\nja %a\n" 5 -stmt: LEU4(mem,rc) "cmp %0,%1\njbe %a\n" 5 -stmt: LTU4(mem,rc) "cmp %0,%1\njb %a\n" 5 -stmt: EQI4(reg,mrc1) "cmp %0,%1\nje %a\n" 4 -stmt: GEI4(reg,mrc1) "cmp %0,%1\njge %a\n" 4 -stmt: GTI4(reg,mrc1) "cmp %0,%1\njg %a\n" 4 -stmt: LEI4(reg,mrc1) "cmp %0,%1\njle %a\n" 4 -stmt: LTI4(reg,mrc1) "cmp %0,%1\njl %a\n" 4 -stmt: NEI4(reg,mrc1) "cmp %0,%1\njne %a\n" 4 - -stmt: EQU4(reg,mrc1) "cmp %0,%1\nje %a\n" 4 -stmt: GEU4(reg,mrc1) "cmp %0,%1\njae %a\n" 4 -stmt: GTU4(reg,mrc1) "cmp %0,%1\nja %a\n" 4 -stmt: LEU4(reg,mrc1) "cmp %0,%1\njbe %a\n" 4 -stmt: LTU4(reg,mrc1) "cmp %0,%1\njb %a\n" 4 -stmt: NEU4(reg,mrc1) "cmp %0,%1\njne %a\n" 4 -cmpf: memf " %0" -cmpf: reg "p" -stmt: EQF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nje %a\n" -stmt: GEF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njbe %a\n" -stmt: GTF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njb %a\n" -stmt: LEF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njae %a\n" -stmt: LTF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nja %a\n" -stmt: NEF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njne %a\n" - -stmt: EQF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nje %a\n" -stmt: GEF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njbe %a\n" -stmt: GTF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njb %a\n" -stmt: LEF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njae %a\n" -stmt: LTF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nja %a\n" -stmt: NEF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njne %a\n" -reg: CALLI4(addrj) "call %0\nadd esp,%a\n" -reg: CALLU4(addrj) "call %0\nadd esp,%a\n" -reg: CALLP4(addrj) "call %0\nadd esp,%a\n" -stmt: CALLV(addrj) "call %0\nadd esp,%a\n" -reg: CALLF4(addrj) "call %0\nadd esp,%a\n" -reg: CALLF8(addrj) "call %0\nadd esp,%a\n" -stmt: CALLF4(addrj) "call %0\nadd esp,%a\nfstp\n" -stmt: CALLF8(addrj) "call %0\nadd esp,%a\nfstp\n" - -stmt: RETI4(reg) "# ret\n" -stmt: RETU4(reg) "# ret\n" -stmt: RETP4(reg) "# ret\n" -stmt: RETF4(reg) "# ret\n" -stmt: RETF8(reg) "# ret\n" -%% -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - parseflags(argc, argv); - intreg[EAX] = mkreg("eax", EAX, 1, IREG); - intreg[EDX] = mkreg("edx", EDX, 1, IREG); - intreg[ECX] = mkreg("ecx", ECX, 1, IREG); - intreg[EBX] = mkreg("ebx", EBX, 1, IREG); - intreg[ESI] = mkreg("esi", ESI, 1, IREG); - intreg[EDI] = mkreg("edi", EDI, 1, IREG); - - shortreg[EAX] = mkreg("ax", EAX, 1, IREG); - shortreg[ECX] = mkreg("cx", ECX, 1, IREG); - shortreg[EDX] = mkreg("dx", EDX, 1, IREG); - shortreg[EBX] = mkreg("bx", EBX, 1, IREG); - shortreg[ESI] = mkreg("si", ESI, 1, IREG); - shortreg[EDI] = mkreg("di", EDI, 1, IREG); - - charreg[EAX] = mkreg("al", EAX, 1, IREG); - charreg[ECX] = mkreg("cl", ECX, 1, IREG); - charreg[EDX] = mkreg("dl", EDX, 1, IREG); - charreg[EBX] = mkreg("bl", EBX, 1, IREG); - for (i = 0; i < 8; i++) - fltreg[i] = mkreg("%d", i, 0, FREG); - charregw = mkwildcard(charreg); - shortregw = mkwildcard(shortreg); - intregw = mkwildcard(intreg); - fltregw = mkwildcard(fltreg); - - tmask[IREG] = (1<<EDI) | (1<<ESI) | (1<<EBX) - | (1<<EDX) | (1<<ECX) | (1<<EAX); - vmask[IREG] = 0; - tmask[FREG] = 0xff; - vmask[FREG] = 0; - print(".486\n"); - print(".model flat\n"); - print("extrn __fltused:near\n"); - print("extrn __ftol:near\n"); - cseg = 0; - quo = mkreg("eax", EAX, 1, IREG); - quo->x.regnode->mask |= 1<<EDX; - rem = mkreg("edx", EDX, 1, IREG); - rem->x.regnode->mask |= 1<<EAX; -} -static Symbol rmap(int opk) { - switch (optype(opk)) { - case B: case P: - return intregw; - case I: case U: - if (opsize(opk) == 1) - return charregw; - else if (opsize(opk) == 2) - return shortregw; - else - return intregw; - case F: - return fltregw; - default: - return 0; - } -} -static void segment(int n) { - if (n == cseg) - return; - if (cseg == CODE || cseg == LIT) - print("_TEXT ends\n"); - else if (cseg == DATA || cseg == BSS) - print("_DATA ends\n"); - cseg = n; - if (cseg == CODE || cseg == LIT) - print("_TEXT segment\n"); - else if (cseg == DATA || cseg == BSS) - print("_DATA segment\n"); -} -static void progend(void) { - segment(0); - print("end\n"); -} -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case MUL+U: - setreg(p, quo); - rtarget(p, 0, intreg[EAX]); - break; - case DIV+I: case DIV+U: - setreg(p, quo); - rtarget(p, 0, quo); - break; - case MOD+I: case MOD+U: - setreg(p, rem); - rtarget(p, 0, quo); - break; - case ASGN+B: - rtarget(p, 0, intreg[EDI]); - rtarget(p->kids[1], 0, intreg[ESI]); - break; - case ARG+B: - rtarget(p->kids[0], 0, intreg[ESI]); - break; - case CVF+I: - setreg(p, intreg[EAX]); - break; - case CALL+I: case CALL+U: case CALL+P: case CALL+V: - setreg(p, intreg[EAX]); - break; - case RET+I: case RET+U: case RET+P: - rtarget(p, 0, intreg[EAX]); - break; - } -} - -static void clobber(Node p) { - static int nstack = 0; - - assert(p); - nstack = ckstack(p, nstack); - switch (specific(p->op)) { - case RSH+I: case RSH+U: case LSH+I: case LSH+U: - if (generic(p->kids[1]->op) != CNST - && !( generic(p->kids[1]->op) == INDIR - && specific(p->kids[1]->kids[0]->op) == VREG+P - && p->kids[1]->syms[RX]->u.t.cse - && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST -)) { - spill(1<<ECX, 1, p); - } - break; - case ASGN+B: case ARG+B: - spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p); - break; - case EQ+F: case LE+F: case GE+F: case LT+F: case GT+F: case NE+F: - spill(1<<EAX, IREG, p); - break; - case CALL+F: - spill(1<<EDX | 1<<EAX | 1<<ECX, IREG, p); - break; - case CALL+I: case CALL+U: case CALL+P: case CALL+V: - spill(1<<EDX | 1<<ECX, IREG, p); - break; - } -} -#define isfp(p) (optype((p)->op)==F) - -int ckstack(Node p, int n) { - int i; - - for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) - if (isfp(p->x.kids[i])) - n--; - if (isfp(p) && p->count > 0) - n++; - if (n > 8) - error("expression too complicated\n"); - debug(fprint(stderr, "(ckstack(%x)=%d)\n", p, n)); - assert(n >= 0); - return n; -} -int memop(Node p) { - assert(p); - assert(generic(p->op) == ASGN); - assert(p->kids[0]); - assert(p->kids[1]); - if (generic(p->kids[1]->kids[0]->op) == INDIR - && sametree(p->kids[0], p->kids[1]->kids[0]->kids[0])) - return 3; - else - return LBURG_MAX; -} -int sametree(Node p, Node q) { - return p == NULL && q == NULL - || p && q && p->op == q->op && p->syms[0] == q->syms[0] - && sametree(p->kids[0], q->kids[0]) - && sametree(p->kids[1], q->kids[1]); -} -static void emit2(Node p) { - int op = specific(p->op); -#define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name) - - if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movsx %s,%s\n", p->syms[RX]->x.name -, preg(charreg)); - else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movsx %s,%s\n", p->syms[RX]->x.name -, preg(charreg)); - else if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movsx %s,%s\n", p->syms[RX]->x.name -, preg(shortreg)); - else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movsx %s,%s\n", p->syms[RX]->x.name -, preg(shortreg)); - - else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movzx %s,%s\n", p->syms[RX]->x.name -, preg(charreg)); - else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movzx %s,%s\n", p->syms[RX]->x.name -, preg(charreg)); - else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movzx %s,%s\n", p->syms[RX]->x.name -, preg(shortreg)); - else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movzx %s,%s\n", p->syms[RX]->x.name -, preg(shortreg)); - else if (generic(op) == CVI || generic(op) == CVU || generic(op) == LOAD) { - char *dst = intreg[getregnum(p)]->x.name; - char *src = preg(intreg); - assert(opsize(p->op) <= opsize(p->x.kids[0]->op)); - if (dst != src) - print("mov %s,%s\n", dst, src); - } -} - -static void doarg(Node p) { - assert(p && p->syms[0]); - mkactual(4, p->syms[0]->u.c.v.i); -} -static void blkfetch(int k, int off, int reg, int tmp) {} -static void blkstore(int k, int off, int reg, int tmp) {} -static void blkloop(int dreg, int doff, int sreg, int soff, - int size, int tmps[]) {} -static void local(Symbol p) { - if (isfloat(p->type)) - p->sclass = AUTO; - if (askregvar(p, (*IR->x.rmap)(ttob(p->type))) == 0) - mkauto(p); -} -static void function(Symbol f, Symbol caller[], Symbol callee[], int n) { - int i; - - print("%s:\n", f->x.name); - print("push ebx\n"); - print("push esi\n"); - print("push edi\n"); - print("push ebp\n"); - print("mov ebp,esp\n"); - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~(unsigned)0; - offset = 16 + 4; - for (i = 0; callee[i]; i++) { - Symbol p = callee[i]; - Symbol q = caller[i]; - assert(q); - p->x.offset = q->x.offset = offset; - p->x.name = q->x.name = stringf("%d", p->x.offset); - p->sclass = q->sclass = AUTO; - offset += roundup(q->type->size, 4); - } - assert(caller[i] == 0); - offset = maxoffset = 0; - gencode(caller, callee); - framesize = roundup(maxoffset, 4); - if (framesize > 0) - print("sub esp,%d\n", framesize); - emitcode(); - print("mov esp,ebp\n"); - print("pop ebp\n"); - print("pop edi\n"); - print("pop esi\n"); - print("pop ebx\n"); - print("ret\n"); -} -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("L%d", genlabel(1)); - else if (p->generated) - p->x.name = stringf("L%s", p->name); - else if (p->scope == GLOBAL || p->sclass == EXTERN) - p->x.name = stringf("_%s", p->name); - else if (p->scope == CONSTANTS - && (isint(p->type) || isptr(p->type)) - && p->name[0] == '0' && p->name[1] == 'x') - p->x.name = stringf("0%sH", &p->name[2]); - else - p->x.name = p->name; -} -static void address(Symbol q, Symbol p, long n) { - if (p->scope == GLOBAL - || p->sclass == STATIC || p->sclass == EXTERN) - q->x.name = stringf("%s%s%D", - p->x.name, n >= 0 ? "+" : "", n); - else { - assert(n <= INT_MAX && n >= INT_MIN); - q->x.offset = p->x.offset + n; - q->x.name = stringd(q->x.offset); - } -} -static void defconst(int suffix, int size, Value v) { - if (suffix == I && size == 1) - print("db %d\n", v.u); - else if (suffix == I && size == 2) - print("dw %d\n", v.i); - else if (suffix == I && size == 4) - print("dd %d\n", v.i); - else if (suffix == U && size == 1) - print("db 0%xH\n", v.u); - else if (suffix == U && size == 2) - print("dw 0%xH\n", v.u); - else if (suffix == U && size == 4) - print("dd 0%xH\n", v.u); - else if (suffix == P && size == 4) - print("dd 0%xH\n", v.p); - else if (suffix == F && size == 4) { - float f = v.d; - print("dd 0%xH\n", *(unsigned *)&f); - } - else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print("dd 0%xH\ndd 0%xH\n", p[swap], p[!swap]); - } - else assert(0); -} -static void defaddress(Symbol p) { - print("dd %s\n", p->x.name); -} -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print("db %d\n", (*s)&0377); -} -static void export(Symbol p) { - print("public %s\n", p->x.name); -} -static void import(Symbol p) { - int oldseg = cseg; - - if (p->ref > 0) { - segment(0); - print("extrn %s:near\n", p->x.name); - segment(oldseg); - } -} -static void global(Symbol p) { - print("align %d\n", - p->type->align > 4 ? 4 : p->type->align); - print("%s label byte\n", p->x.name); - if (p->u.seg == BSS) - print("db %d dup (0)\n", p->type->size); -} -static void space(int n) { - if (cseg != BSS) - print("db %d dup (0)\n", n); -} -Interface x86IR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 4, 1, /* double */ - 8, 4, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 4, 0, /* struct; so that ARGB keeps stack aligned */ - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 0, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - 0, 0, 0, 0, 0, 0, 0, - {1, rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, -} -}; -static char rcsid[] = "$Id: x86.md 145 2001-10-17 21:53:10Z timo $"; diff --git a/code/tools/lcc/src/x86linux.md b/code/tools/lcc/src/x86linux.md deleted file mode 100644 index d185f56..0000000 --- a/code/tools/lcc/src/x86linux.md +++ /dev/null @@ -1,1081 +0,0 @@ -%{ -/* x86/linux lburg spec. Derived from x86.md by -Marcos Ramirez <marcos@inf.utfsm.cl> -Horst von Brand <vonbrand@sleipnir.valparaiso.cl> -Jacob Navia <jacob@jacob.remcomp.fr> -*/ -enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 }; -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -extern int ckstack(Node, int); -extern int memop(Node); -extern int sametree(Node, Node); -static Symbol charreg[32], shortreg[32], intreg[32]; -static Symbol fltreg[32]; - -static Symbol charregw, shortregw, intregw, fltregw; - -static int cseg; - -static Symbol quo, rem; - -extern char *stabprefix; -extern void stabblock(int, int, Symbol*); -extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *); -extern void stabfend(Symbol, int); -extern void stabinit(char *, int, char *[]); -extern void stabline(Coordinate *); -extern void stabsym(Symbol); -extern void stabtype(Symbol); - -static int pflag = 0; -static char rcsid[] = "$Id: x86linux.md 145 2001-10-17 21:53:10Z timo $"; - -#define hasargs(p) (p->syms[0] && p->syms[0]->u.c.v.i > 0 ? 0 : LBURG_MAX) -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -freg: INDIRF4(VREGP) "# read register\n" -freg: INDIRF8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" - -cnst: CNSTI1 "%a" -cnst: CNSTU1 "%a" - -cnst: CNSTI2 "%a" -cnst: CNSTU2 "%a" - -cnst: CNSTI4 "%a" -cnst: CNSTU4 "%a" -cnst: CNSTP4 "%a" - -cnst: CNSTI8 "%a" -cnst: CNSTU8 "%a" -cnst: CNSTP8 "%a" - -con: cnst "$%0" - -stmt: reg "" -stmt: freg "" - -acon: ADDRGP4 "%a" -acon: ADDRGP8 "%a" -acon: cnst "%0" - -baseaddr: ADDRGP4 "%a" -base: reg "(%0)" -base: ADDI4(reg,acon) "%1(%0)" -base: ADDP4(reg,acon) "%1(%0)" -base: ADDU4(reg,acon) "%1(%0)" -base: ADDRFP4 "%a(%%ebp)" -base: ADDRLP4 "%a(%%ebp)" - -index: reg "%0" -index: LSHI4(reg,con1) "%0,2" -index: LSHI4(reg,con2) "%0,4" -index: LSHI4(reg,con3) "%0,8" -index: LSHU4(reg,con1) "%0,2" -index: LSHU4(reg,con2) "%0,4" -index: LSHU4(reg,con3) "%0,8" - -con0: CNSTI4 "1" range(a, 0, 0) -con0: CNSTU4 "1" range(a, 0, 0) -con1: CNSTI4 "1" range(a, 1, 1) -con1: CNSTU4 "1" range(a, 1, 1) -con2: CNSTI4 "2" range(a, 2, 2) -con2: CNSTU4 "2" range(a, 2, 2) -con3: CNSTI4 "3" range(a, 3, 3) -con3: CNSTU4 "3" range(a, 3, 3) - -addr: base "%0" -addr: baseaddr "%0" -addr: ADDI4(index,baseaddr) "%1(,%0)" -addr: ADDP4(index,baseaddr) "%1(,%0)" -addr: ADDU4(index,baseaddr) "%1(,%0)" - -addr: ADDI4(reg,baseaddr) "%1(%0)" -addr: ADDP4(reg,baseaddr) "%1(%0)" -addr: ADDU4(reg,baseaddr) "%1(%0)" - -addr: ADDI4(index,reg) "(%1,%0)" -addr: ADDP4(index,reg) "(%1,%0)" -addr: ADDU4(index,reg) "(%1,%0)" - -addr: index "(,%0)" - -mem1: INDIRI1(addr) "%0" -mem1: INDIRU1(addr) "%0" -mem2: INDIRI2(addr) "%0" -mem2: INDIRU2(addr) "%0" -mem4: INDIRI4(addr) "%0" -mem4: INDIRU4(addr) "%0" -mem4: INDIRP4(addr) "%0" - -rc: reg "%0" -rc: con "%0" - -mr: reg "%0" -mr: mem4 "%0" - -mr1: reg "%0" -mr1: mem1 "%0" - -mr2: reg "%0" -mr2: mem2 "%0" - -mrc: mem4 "%0" 1 -mrc: mem1 "%0" 1 -mrc: mem2 "%0" 1 -mrc: rc "%0" - -reg: addr "leal %0,%c\n" 1 -reg: mr "movl %0,%c\n" 1 -reg: mr1 "movb %0,%c\n" 1 -reg: mr2 "movw %0,%c\n" 1 -reg: con "movl %0,%c\n" 1 - -reg: LOADI1(reg) "# move\n" 1 -reg: LOADI2(reg) "# move\n" 1 -reg: LOADI4(reg) "# move\n" move(a) -reg: LOADU1(reg) "# move\n" 1 -reg: LOADU2(reg) "# move\n" 1 -reg: LOADU4(reg) "# move\n" move(a) -reg: LOADP4(reg) "# move\n" move(a) -reg: ADDI4(reg,mrc) "?movl %0,%c\naddl %1,%c\n" 1 -reg: ADDP4(reg,mrc) "?movl %0,%c\naddl %1,%c\n" 1 -reg: ADDU4(reg,mrc) "?movl %0,%c\naddl %1,%c\n" 1 -reg: SUBI4(reg,mrc) "?movl %0,%c\nsubl %1,%c\n" 1 -reg: SUBP4(reg,mrc) "?movl %0,%c\nsubl %1,%c\n" 1 -reg: SUBU4(reg,mrc) "?movl %0,%c\nsubl %1,%c\n" 1 -reg: BANDI4(reg,mrc) "?movl %0,%c\nandl %1,%c\n" 1 -reg: BORI4(reg,mrc) "?movl %0,%c\norl %1,%c\n" 1 -reg: BXORI4(reg,mrc) "?movl %0,%c\nxorl %1,%c\n" 1 -reg: BANDU4(reg,mrc) "?movl %0,%c\nandl %1,%c\n" 1 -reg: BORU4(reg,mrc) "?movl %0,%c\norl %1,%c\n" 1 -reg: BXORU4(reg,mrc) "?movl %0,%c\nxorl %1,%c\n" 1 - -stmt: ASGNI4(addr,ADDI4(mem4,con1)) "incl %1\n" memop(a) -stmt: ASGNI4(addr,ADDU4(mem4,con1)) "incl %1\n" memop(a) -stmt: ASGNP4(addr,ADDP4(mem4,con1)) "incl %1\n" memop(a) -stmt: ASGNI4(addr,SUBI4(mem4,con1)) "decl %1\n" memop(a) -stmt: ASGNI4(addr,SUBU4(mem4,con1)) "decl %1\n" memop(a) -stmt: ASGNP4(addr,SUBP4(mem4,con1)) "decl %1\n" memop(a) -stmt: ASGNI4(addr,ADDI4(mem4,rc)) "addl %2,%1\n" memop(a) -stmt: ASGNI4(addr,SUBI4(mem4,rc)) "sub %2,%1\n" memop(a) -stmt: ASGNU4(addr,ADDU4(mem4,rc)) "add %2,%1\n" memop(a) -stmt: ASGNU4(addr,SUBU4(mem4,rc)) "sub %2,%1\n" memop(a) - -stmt: ASGNI4(addr,BANDI4(mem4,rc)) "andl %2,%1\n" memop(a) -stmt: ASGNI4(addr,BORI4(mem4,rc)) "orl %2,%1\n" memop(a) -stmt: ASGNI4(addr,BXORI4(mem4,rc)) "xorl %2,%1\n" memop(a) -stmt: ASGNU4(addr,BANDU4(mem4,rc)) "andl %2,%1\n" memop(a) -stmt: ASGNU4(addr,BORU4(mem4,rc)) "orl %2,%1\n" memop(a) -stmt: ASGNU4(addr,BXORU4(mem4,rc)) "xorl %2,%1\n" memop(a) -reg: BCOMI4(reg) "?movl %0,%c\nnotl %c\n" 2 -reg: BCOMU4(reg) "?movl %0,%c\nnotl %c\n" 2 -reg: NEGI4(reg) "?movl %0,%c\nnegl %c\n" 2 - -stmt: ASGNI4(addr,BCOMI4(mem4)) "notl %1\n" memop(a) -stmt: ASGNU4(addr,BCOMU4(mem4)) "notl %1\n" memop(a) -stmt: ASGNI4(addr,NEGI4(mem4)) "negl %1\n" memop(a) -reg: LSHI4(reg,rc5) "?movl %0,%c\nsall %1,%c\n" 2 -reg: LSHU4(reg,rc5) "?movl %0,%c\nshll %1,%c\n" 2 -reg: RSHI4(reg,rc5) "?movl %0,%c\nsarl %1,%c\n" 2 -reg: RSHU4(reg,rc5) "?movl %0,%c\nshrl %1,%c\n" 2 - -stmt: ASGNI4(addr,LSHI4(mem4,rc5)) "sall %2,%1\n" memop(a) -stmt: ASGNI4(addr,LSHU4(mem4,rc5)) "shll %2,%1\n" memop(a) -stmt: ASGNI4(addr,RSHI4(mem4,rc5)) "sarl %2,%1\n" memop(a) -stmt: ASGNI4(addr,RSHU4(mem4,rc5)) "shrl %2,%1\n" memop(a) - -rc5: CNSTI4 "$%a" range(a, 0, 31) -rc5: reg "%%cl" -reg: MULI4(reg,mrc) "?movl %0,%c\nimull %1,%c\n" 14 -reg: MULI4(con,mr) "imul %0,%1,%c\n" 13 -reg: MULU4(reg,mr) "mull %1\n" 13 -reg: DIVU4(reg,reg) "xorl %%edx,%%edx\ndivl %1\n" -reg: MODU4(reg,reg) "xorl %%edx,%%edx\ndivl %1\n" -reg: DIVI4(reg,reg) "cdq\nidivl %1\n" -reg: MODI4(reg,reg) "cdq\nidivl %1\n" -reg: CVPU4(reg) "movl %0,%c\n" move(a) -reg: CVUP4(reg) "movl %0,%c\n" move(a) -reg: CVII4(INDIRI1(addr)) "movsbl %0,%c\n" 3 -reg: CVII4(INDIRI2(addr)) "movswl %0,%c\n" 3 -reg: CVUU4(INDIRU1(addr)) "movzbl %0,%c\n" 3 -reg: CVUU4(INDIRU2(addr)) "movzwl %0,%c\n" 3 -reg: CVII4(reg) "# extend\n" 3 -reg: CVIU4(reg) "# extend\n" 3 -reg: CVUI4(reg) "# extend\n" 3 -reg: CVUU4(reg) "# extend\n" 3 - -reg: CVII1(reg) "# truncate\n" 1 -reg: CVII2(reg) "# truncate\n" 1 -reg: CVUU1(reg) "# truncate\n" 1 -reg: CVUU2(reg) "# truncate\n" 1 - -mrca: mem4 "%0" -mrca: rc "%0" -mrca: ADDRGP4 "$%a" -mrca: ADDRGP8 "$%a" - -stmt: ASGNI1(addr,rc) "movb %1,%0\n" 1 -stmt: ASGNI2(addr,rc) "movw %1,%0\n" 1 -stmt: ASGNI4(addr,rc) "movl %1,%0\n" 1 -stmt: ASGNU1(addr,rc) "movb %1,%0\n" 1 -stmt: ASGNU2(addr,rc) "movw %1,%0\n" 1 -stmt: ASGNU4(addr,rc) "movl %1,%0\n" 1 -stmt: ASGNP4(addr,rc) "movl %1,%0\n" 1 -stmt: ARGI4(mrca) "pushl %0\n" 1 -stmt: ARGU4(mrca) "pushl %0\n" 1 -stmt: ARGP4(mrca) "pushl %0\n" 1 -stmt: ASGNB(reg,INDIRB(reg)) "movl $%a,%%ecx\nrep\nmovsb\n" -stmt: ARGB(INDIRB(reg)) "subl $%a,%%esp\nmovl %%esp,%%edi\nmovl $%a,%%ecx\nrep\nmovsb\n" - -memf: INDIRF8(addr) "l %0" -memf: INDIRF4(addr) "s %0" -memf: CVFF8(INDIRF4(addr)) "s %0" -memf: CVFF4(INDIRF8(addr)) "l %0" - -freg: memf "fld%0\n" 3 - -stmt: ASGNF8(addr,freg) "fstpl %0\n" 7 -stmt: ASGNF4(addr,freg) "fstps %0\n" 7 -stmt: ASGNF4(addr,CVFF4(freg)) "fstps %0\n" 7 - -stmt: ARGF8(freg) "subl $8,%%esp\nfstpl (%%esp)\n" -stmt: ARGF4(freg) "subl $4,%%esp\nfstps (%%esp)\n" -freg: NEGF8(freg) "fchs\n" -freg: NEGF4(freg) "fchs\n" - -flt: memf "%0" -flt: freg "p %%st(1),%%st" - -freg: ADDF4(freg,flt) "fadd%1\n" -freg: ADDF8(freg,flt) "fadd%1\n" - -freg: DIVF4(freg,flt) "fdiv%1\n" -freg: DIVF8(freg,flt) "fdiv%1\n" - -freg: MULF4(freg,flt) "fmul%1\n" -freg: MULF8(freg,flt) "fmul%1\n" - -freg: SUBF4(freg,flt) "fsub%1\n" -freg: SUBF8(freg,flt) "fsub%1\n" - -freg: CVFF8(freg) "# CVFF8\n" -freg: CVFF4(freg) "sub $4,%%esp\nfstps (%%esp)\nflds (%%esp)\naddl $4,%%esp\n" 12 - -stmt: ASGNI4(addr,CVFI4(freg)) "fistpl %0\n" 29 -reg: CVFI4(freg) "subl $4,%%esp\nfistpl 0(%%esp)\npopl %c\n" 31 - -freg: CVIF8(INDIRI4(addr)) "fildl %0\n" 10 -freg: CVIF8(reg) "pushl %0\nfildl (%%esp)\naddl $4,%%esp\n" 12 - -freg: CVIF4(INDIRI4(addr)) "fildl %0\n" 10 -freg: CVIF4(reg) "pushl %0\nfildl (%%esp)\naddl $4,%%esp\n" 12 - -addrj: ADDRGP4 "%a" -addrj: reg "*%0" 2 -addrj: mem4 "*%0" 2 - -stmt: LABELV "%a:\n" -stmt: JUMPV(addrj) "jmp %0\n" 3 -stmt: EQI4(mem4,rc) "cmpl %1,%0\nje %a\n" 5 -stmt: GEI4(mem4,rc) "cmpl %1,%0\njge %a\n" 5 -stmt: GTI4(mem4,rc) "cmpl %1,%0\njg %a\n" 5 -stmt: LEI4(mem4,rc) "cmpl %1,%0\njle %a\n" 5 -stmt: LTI4(mem4,rc) "cmpl %1,%0\njl %a\n" 5 -stmt: NEI4(mem4,rc) "cmpl %1,%0\njne %a\n" 5 -stmt: GEU4(mem4,rc) "cmpl %1,%0\njae %a\n" 5 -stmt: GTU4(mem4,rc) "cmpl %1,%0\nja %a\n" 5 -stmt: LEU4(mem4,rc) "cmpl %1,%0\njbe %a\n" 5 -stmt: LTU4(mem4,rc) "cmpl %1,%0\njb %a\n" 5 -stmt: EQI4(reg,mrc) "cmpl %1,%0\nje %a\n" 4 -stmt: GEI4(reg,mrc) "cmpl %1,%0\njge %a\n" 4 -stmt: GTI4(reg,mrc) "cmpl %1,%0\njg %a\n" 4 -stmt: LEI4(reg,mrc) "cmpl %1,%0\njle %a\n" 4 -stmt: LTI4(reg,mrc) "cmpl %1,%0\njl %a\n" 4 -stmt: NEI4(reg,mrc) "cmpl %1,%0\njne %a\n" 4 - -stmt: EQU4(reg,mrc) "cmpl %1,%0\nje %a\n" 4 -stmt: GEU4(reg,mrc) "cmpl %1,%0\njae %a\n" 4 -stmt: GTU4(reg,mrc) "cmpl %1,%0\nja %a\n" 4 -stmt: LEU4(reg,mrc) "cmpl %1,%0\njbe %a\n" 4 -stmt: LTU4(reg,mrc) "cmpl %1,%0\njb %a\n" 4 -stmt: NEU4(reg,mrc) "cmpl %1,%0\njne %a\n" 4 - -stmt: EQI4(BANDU4(mr,con),con0) "testl %1,%0\nje %a\n" 3 -stmt: NEI4(BANDU4(mr,con),con0) "testl %1,%0\njne %a\n" - -stmt: EQI4(BANDU4(CVII2(INDIRI2(addr)),con),con0) "testw %1,%0\nje %a\n" -stmt: NEI4(BANDU4(CVII2(INDIRI2(addr)),con),con0) "testw %1,%0\njne %a\n" -stmt: EQI4(BANDU4(CVIU2(INDIRI2(addr)),con),con0) "testw %1,%0\nje %a\n" -stmt: NEI4(BANDU4(CVIU2(INDIRI2(addr)),con),con0) "testw %1,%0\njne %a\n" -stmt: EQI4(BANDU4(CVII1(INDIRI1(addr)),con),con0) "testb %1,%0\nje %a\n" - -cmpf: INDIRF8(addr) "l %0" -cmpf: INDIRF4(addr) "s %0" -cmpf: CVFF8(INDIRF4(addr)) "s %0" -cmpf: freg "p" - -stmt: EQF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\nje %a\n" -stmt: GEF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njbe %a\n" -stmt: GTF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njb %a\n" -stmt: LEF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njae %a\n" -stmt: LTF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\nja %a\n" -stmt: NEF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njne %a\n" - -stmt: EQF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\nje %a\n" -stmt: GEF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njbe %a\n" -stmt: GTF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njb %a\n" -stmt: LEF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njae %a\n" -stmt: LTF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\nja %a\n" -stmt: NEF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njne %a\n" - -freg: DIVF8(freg,CVIF8(INDIRI4(addr))) "fidivl %1\n" -freg: DIVF8(CVIF8(INDIRI4(addr)),freg) "fidivrl %0\n" -freg: DIVF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "fidivs %1\n" -freg: DIVF8(CVIF8(CVII2(INDIRI2(addr))),freg) "fidivrs %0\n" -freg: MULF8(freg,CVIF8(INDIRI4(addr))) "fimull %1\n" -freg: MULF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "fimuls %1\n" -freg: SUBF8(freg,CVIF8(INDIRI4(addr))) "fisubl %1\n" -freg: SUBF8(CVIF8(INDIRI4(addr)),freg) "fisubrl %0\n" -freg: SUBF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "fisubs %1\n" -freg: SUBF8(CVIF8(CVII2(INDIRI2(addr))),freg) "fisubrs %0\n" -freg: ADDF8(freg,CVIF8(INDIRI4(addr))) "fiaddl %1\n" -freg: ADDF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "fiadds %1\n" -freg: ADDF8(freg,CVFF8(INDIRF4(addr))) "fdivs %1\n" -freg: SUBF8(freg,CVFF8(INDIRF4(addr))) "fsubs %1\n" -freg: MULF8(freg,CVFF8(INDIRF4(addr))) "fmuls %1\n" -freg: DIVF8(freg,CVFF8(INDIRF4(addr))) "fdivs %1\n" -freg: LOADF8(memf) "fld%0\n" - -reg: CALLI4(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -reg: CALLU4(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -reg: CALLP4(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) - -reg: CALLI4(addrj) "call %0\n" 1 -reg: CALLU4(addrj) "call %0\n" 1 -reg: CALLP4(addrj) "call %0\n" 1 - -stmt: CALLV(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -stmt: CALLV(addrj) "call %0\n" 1 - -freg: CALLF4(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -freg: CALLF4(addrj) "call %0\n" 1 - -stmt: CALLF4(addrj) "call %0\naddl $%a,%%esp\nfstp %%st(0)\n" hasargs(a) -stmt: CALLF4(addrj) "call %0\nfstp %%st(0)\n" 1 - -freg: CALLF8(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -freg: CALLF8(addrj) "call %0\n" 1 - -stmt: CALLF8(addrj) "call %0\naddl $%a,%%esp\nfstp %%st(0)\n" hasargs(a) -stmt: CALLF8(addrj) "call %0\nfstp %%st(0)\n" 1 - -stmt: RETI4(reg) "# ret\n" -stmt: RETU4(reg) "# ret\n" -stmt: RETP4(reg) "# ret\n" -stmt: RETF4(freg) "# ret\n" -stmt: RETF8(freg) "# ret\n" -%% -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - parseflags(argc, argv); - for (i = 0; i < argc; i++) - if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-pg") == 0) - pflag = 1; - intreg[EAX] = mkreg("%%eax", EAX, 1, IREG); - intreg[EDX] = mkreg("%%edx", EDX, 1, IREG); - intreg[ECX] = mkreg("%%ecx", ECX, 1, IREG); - intreg[EBX] = mkreg("%%ebx", EBX, 1, IREG); - intreg[ESI] = mkreg("%%esi", ESI, 1, IREG); - intreg[EDI] = mkreg("%%edi", EDI, 1, IREG); - shortreg[EAX] = mkreg("%%ax", EAX, 1, IREG); - shortreg[ECX] = mkreg("%%cx", ECX, 1, IREG); - shortreg[EDX] = mkreg("%%dx", EDX, 1, IREG); - shortreg[EBX] = mkreg("%%bx", EBX, 1, IREG); - shortreg[ESI] = mkreg("%%si", ESI, 1, IREG); - shortreg[EDI] = mkreg("%%di", EDI, 1, IREG); - charreg[EAX] = mkreg("%%al", EAX, 1, IREG); - charreg[ECX] = mkreg("%%cl", ECX, 1, IREG); - charreg[EDX] = mkreg("%%dl", EDX, 1, IREG); - charreg[EBX] = mkreg("%%bl", EBX, 1, IREG); - for (i = 0; i < 8; i++) - fltreg[i] = mkreg("%d", i, 0, FREG); - charregw = mkwildcard(charreg); - shortregw = mkwildcard(shortreg); - intregw = mkwildcard(intreg); - fltregw = mkwildcard(fltreg); - - tmask[IREG] = (1<<EDI) | (1<<ESI) | (1<<EBX) - | (1<<EDX) | (1<<ECX) | (1<<EAX); - vmask[IREG] = 0; - tmask[FREG] = 0xff; - vmask[FREG] = 0; - - cseg = 0; - quo = mkreg("%%eax", EAX, 1, IREG); - quo->x.regnode->mask |= 1<<EDX; - rem = mkreg("%%edx", EDX, 1, IREG); - rem->x.regnode->mask |= 1<<EAX; - - stabprefix = ".LL"; -} - -static Symbol rmap(int opk) { - switch (optype(opk)) { - case B: case P: - return intregw; - case I: case U: - if (opsize(opk) == 1) - return charregw; - else if (opsize(opk) == 2) - return shortregw; - else - return intregw; - case F: - return fltregw; - default: - return 0; - } -} - -static Symbol prevg; - -static void globalend(void) { - if (prevg && prevg->type->size > 0) - print(".size %s,%d\n", prevg->x.name, prevg->type->size); - prevg = NULL; -} - -static void progend(void) { - globalend(); - (*IR->segment)(CODE); - print(".ident \"LCC: 4.1\"\n"); -} - -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case RSH+I: case RSH+U: case LSH+I: case LSH+U: - if (generic(p->kids[1]->op) != CNST - && !( generic(p->kids[1]->op) == INDIR - && specific(p->kids[1]->kids[0]->op) == VREG+P - && p->kids[1]->syms[RX]->u.t.cse - && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST)) { - rtarget(p, 1, intreg[ECX]); - setreg(p, intreg[EAX]); - } - break; - case MUL+U: - setreg(p, quo); - rtarget(p, 0, intreg[EAX]); - break; - case DIV+I: case DIV+U: - setreg(p, quo); - rtarget(p, 0, intreg[EAX]); - rtarget(p, 1, intreg[ECX]); - break; - case MOD+I: case MOD+U: - setreg(p, rem); - rtarget(p, 0, intreg[EAX]); - rtarget(p, 1, intreg[ECX]); - break; - case ASGN+B: - rtarget(p, 0, intreg[EDI]); - rtarget(p->kids[1], 0, intreg[ESI]); - break; - case ARG+B: - rtarget(p->kids[0], 0, intreg[ESI]); - break; - case CVF+I: - setreg(p, intreg[EAX]); - break; - case CALL+I: case CALL+U: case CALL+P: case CALL+V: - setreg(p, intreg[EAX]); - break; - case RET+I: case RET+U: case RET+P: - rtarget(p, 0, intreg[EAX]); - break; - } -} - -static void clobber(Node p) { - static int nstack = 0; - - assert(p); - nstack = ckstack(p, nstack); - switch (specific(p->op)) { - case ASGN+B: case ARG+B: - spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p); - break; - case EQ+F: case LE+F: case GE+F: case LT+F: case GT+F: case NE+F: - spill(1<<EAX, IREG, p); - break; - case CALL+F: - spill(1<<EDX | 1<<EAX | 1<<ECX, IREG, p); - break; - case CALL+I: case CALL+U: case CALL+P: case CALL+V: - spill(1<<EDX | 1<<ECX, IREG, p); - break; - } -} - -static void emit2(Node p) { - int op = specific(p->op); -#define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name) - - if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movsbl %s,%s\n", preg(charreg), p->syms[RX]->x.name); - else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movsbl %s,%s\n", preg(charreg), p->syms[RX]->x.name); - else if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movswl %s,%s\n", preg(shortreg), p->syms[RX]->x.name); - else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movswl %s,%s\n", preg(shortreg), p->syms[RX]->x.name); - else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movzbl %s,%s\n", preg(charreg), p->syms[RX]->x.name); - else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movzbl %s,%s\n", preg(charreg), p->syms[RX]->x.name); - else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movzwl %s,%s\n", preg(shortreg), p->syms[RX]->x.name); - else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movzwl %s,%s\n", preg(shortreg), p->syms[RX]->x.name); - else if (generic(op) == CVI || generic(op) == CVU || generic(op) == LOAD) { - char *dst = intreg[getregnum(p)]->x.name; - char *src = preg(intreg); - assert(opsize(p->op) <= opsize(p->x.kids[0]->op)); - if (dst != src) - print("movl %s,%s\n", src, dst); - } -} - -static void function(Symbol f, Symbol caller[], Symbol callee[], int n) { - int i; - - globalend(); - print(".align 16\n"); - print(".type %s,@function\n", f->x.name); - print("%s:\n", f->x.name); - print("pushl %%ebp\n"); - if (pflag) { - static int plab; - print("movl %%esp,%%ebp\n"); - (*IR->segment)(DATA); - print(".align 4\n.LP%d:\n.long 0\n", plab); - (*IR->segment)(CODE); - print("movl $.LP%d,%%edx\ncall mcount\n", plab); - plab++; - } - print("pushl %%ebx\n"); - print("pushl %%esi\n"); - print("pushl %%edi\n"); - print("movl %%esp,%%ebp\n"); - - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~0U; - offset = 16 + 4; - for (i = 0; callee[i]; i++) { - Symbol p = callee[i]; - Symbol q = caller[i]; - assert(q); - offset = roundup(offset, q->type->align); - p->x.offset = q->x.offset = offset; - p->x.name = q->x.name = stringf("%d", p->x.offset); - p->sclass = q->sclass = AUTO; - offset += roundup(q->type->size, 4); - } - assert(caller[i] == 0); - offset = maxoffset = 0; - gencode(caller, callee); - framesize = roundup(maxoffset, 4); - if (framesize > 0) - print("subl $%d,%%esp\n", framesize); - emitcode(); - print("movl %%ebp,%%esp\n"); - print("popl %%edi\n"); - print("popl %%esi\n"); - print("popl %%ebx\n"); - print("popl %%ebp\n"); - print("ret\n"); - { int l = genlabel(1); - print(".Lf%d:\n", l); - print(".size %s,.Lf%d-%s\n", f->x.name, l, f->x.name); - } -} - -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("%s.%d", p->name, genlabel(1)); - else if (p->generated) - p->x.name = stringf(".LC%s", p->name); - else if (p->scope == GLOBAL || p->sclass == EXTERN) - p->x.name = stringf("%s", p->name); - else - p->x.name = p->name; -} - -static void segment(int n) { - if (n == cseg) - return; - cseg = n; - if (cseg == CODE) - print(".text\n"); - else if (cseg == BSS) - print(".bss\n"); - else if (cseg == DATA || cseg == LIT) - print(".data\n"); -} - -static void defconst(int suffix, int size, Value v) { - if (suffix == I && size == 1) - print(".byte %d\n", v.u); - else if (suffix == I && size == 2) - print(".word %d\n", v.i); - else if (suffix == I && size == 4) - print(".long %d\n", v.i); - else if (suffix == U && size == 1) - print(".byte %d\n", v.u); - else if (suffix == U && size == 2) - print(".word %d\n", v.u); - else if (suffix == U && size == 4) - print(".long %d\n", v.u); - else if (suffix == P && size == 4) - print(".long %d\n", v.p); - else if (suffix == F && size == 4) { - float f = v.d; - print(".long %d\n", *(unsigned *)&f); - } else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print(".long %d\n.long %d\n", p[swap], p[!swap]); - } - else assert(0); -} - -static void defaddress(Symbol p) { - print(".long %s\n", p->x.name); -} - -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print(".byte %d\n", (*s)&0377); -} - -static void export(Symbol p) { - globalend(); - print(".globl %s\n", p->x.name); -} - -static void import(Symbol p) {} - -static void global(Symbol p) { - globalend(); - print(".align %d\n", p->type->align > 4 ? 4 : p->type->align); - if (!p->generated) { - print(".type %s,@%s\n", p->x.name, - isfunc(p->type) ? "function" : "object"); - if (p->type->size > 0) - print(".size %s,%d\n", p->x.name, p->type->size); - else - prevg = p; - } - if (p->u.seg == BSS) { - if (p->sclass == STATIC) - print(".lcomm %s,%d\n", p->x.name, p->type->size); - else - print(".comm %s,%d\n", p->x.name, p->type->size); - } else { - print("%s:\n", p->x.name); - } -} - -static void space(int n) { - if (cseg != BSS) - print(".space %d\n", n); -} - -Interface x86linuxIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 4, 1, /* double */ - 8, 4, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 4, 0, /* struct; so that ARGB keeps stack aligned */ - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 0, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - 0, /* address */ - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - 0, /* local */ - progbeg, - progend, - segment, - space, - stabblock, stabend, 0, stabinit, stabline, stabsym, stabtype, - {1, rmap, - 0, 0, 0, /* blkfetch, blkstore, blkloop */ - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - 0, /* doarg */ - target, - clobber, - } -}; - -void x86linux_init(int argc, char *argv[]) { - static int inited; - extern Interface x86IR; - - if (inited) - return; - inited = 1; -#define xx(f) assert(!x86linuxIR.f); x86linuxIR.f = x86IR.f - xx(address); - xx(local); - xx(x.blkfetch); - xx(x.blkstore); - xx(x.blkloop); - xx(x.doarg); -#undef xx -} |