%{ #define STACK_MACHINE #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) #define REGS 0xffffffff static void address(Symbol, Symbol, long); static void defaddress(Symbol); static void defconst(int, int, Value); static void defstring(int, char *); static void defsymbol(Symbol); static void emit2(Node); static void export(Symbol); 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); extern void stackemit(Node forest); extern Node stackgen(Node forest); extern void swtch(Symbol label); %} %start stmt %term CNSTF4=4113 %term CNSTI1=1045 %term CNSTI2=2069 %term CNSTI4=4117 %term CNSTP4=4119 %term CNSTU1=1046 %term CNSTU2=2070 %term CNSTU4=4118 %term ARGB=41 %term ARGF4=4129 %term ARGI4=4133 %term ARGP4=4135 %term ARGU4=4134 %term ASGNB=57 %term ASGNF4=4145 %term ASGNI1=1077 %term ASGNI2=2101 %term ASGNI4=4149 %term ASGNP4=4151 %term ASGNU1=1078 %term ASGNU2=2102 %term ASGNU4=4150 %term INDIRB=73 %term INDIRF4=4161 %term INDIRI1=1093 %term INDIRI2=2117 %term INDIRI4=4165 %term INDIRP4=4167 %term INDIRU1=1094 %term INDIRU2=2118 %term INDIRU4=4166 %term CVFF4=4209 %term CVFI4=4213 %term CVIF4=4225 %term CVII1=1157 %term CVII2=2181 %term CVII4=4229 %term CVIU1=1158 %term CVIU2=2182 %term CVIU4=4230 %term CVPP4=4247 %term CVPU4=4246 %term CVUI1=1205 %term CVUI2=2229 %term CVUI4=4277 %term CVUP4=4279 %term CVUU1=1206 %term CVUU2=2230 %term CVUU4=4278 %term NEGF4=4289 %term NEGI4=4293 %term CALLB=217 %term CALLF4=4305 %term CALLI4=4309 %term CALLP4=4311 %term CALLU4=4310 %term CALLV=216 %term RETF4=4337 %term RETI4=4341 %term RETP4=4343 %term RETU4=4342 %term RETV=248 %term ADDRGP4=4359 %term ADDRFP4=4375 %term ADDRLP4=4391 %term ADDF4=4401 %term ADDI4=4405 %term ADDP4=4407 %term ADDU4=4406 %term SUBF4=4417 %term SUBI4=4421 %term SUBP4=4423 %term SUBU4=4422 %term LSHI4=4437 %term LSHU4=4438 %term MODI4=4453 %term MODU4=4454 %term RSHI4=4469 %term RSHU4=4470 %term BANDI4=4485 %term BANDU4=4486 %term BCOMI4=4501 %term BCOMU4=4502 %term BORI4=4517 %term BORU4=4518 %term BXORI4=4533 %term BXORU4=4534 %term DIVF4=4545 %term DIVI4=4549 %term DIVU4=4550 %term MULF4=4561 %term MULI4=4565 %term MULU4=4566 %term EQF4=4577 %term EQI4=4581 %term EQU4=4582 %term GEF4=4593 %term GEI4=4597 %term GEU4=4598 %term GTF4=4609 %term GTI4=4613 %term GTU4=4614 %term LEF4=4625 %term LEI4=4629 %term LEU4=4630 %term LTF4=4641 %term LTI4=4645 %term LTU4=4646 %term NEF4=4657 %term NEI4=4661 %term NEU4=4662 %term JUMPV=584 %term LABELV=600 %term LOADB=233 %term LOADF4=4321 %term LOADI1=1253 %term LOADI2=2277 %term LOADI4=4325 %term LOADP4=4327 %term LOADU1=1254 %term LOADU2=2278 %term LOADU4=4326 %term VREGP=711 %term STACKP=727 %term COPYP=759 %term TUCKI1=1765 %term TUCKU1=1766 %term TUCKI2=2789 %term TUCKU2=2790 %term TUCKF4=4833 %term TUCKI4=4837 %term TUCKP4=4839 %term TUCKU4=4838 %term NOOP = 48 %% sread: STACKP "\n" range(a, 1, 1) sread: STACKP "swap\n" range(a, 2, 2)+1 sread: STACKP "rsd3\n" range(a, 3, 3)+1 sread: STACKP "rsd4\n" range(a, 4, 4)+1 sread: COPYP "copy%b\n" range(a, 1, 4)+1 sread: COPYP "any\n" range(a, 0, 0) sread: VREGP "ERROR - FORGOTTEN VIRTUAL!\n" drop: STACKP "drop\n" range(a, 1, 1)+1 drop: STACKP "drop%b\n" range(a, 2, 4)+1 stmt: INDIRI1(drop) "\n" stmt: INDIRU1(drop) "\n" stmt: INDIRI2(drop) "\n" stmt: INDIRU2(drop) "\n" stmt: INDIRF4(drop) "\n" stmt: INDIRI4(drop) "\n" stmt: INDIRP4(drop) "\n" stmt: INDIRU4(drop) "\n" stk: INDIRI1(sread) "\n" stk: INDIRU1(sread) "\n" stk: INDIRI2(sread) "\n" stk: INDIRU2(sread) "\n" stk: INDIRF4(sread) "\n" stk: INDIRI4(sread) "\n" stk: INDIRP4(sread) "\n" stk: INDIRU4(sread) "\n" tuck1: TUCKI1(stk) "\n" range(a, 1, 1) tuck1: TUCKU1(stk) "\n" range(a, 1, 1) tuck1: TUCKI2(stk) "\n" range(a, 1, 1) tuck1: TUCKU2(stk) "\n" range(a, 1, 1) tuck1: TUCKI4(stk) "\n" range(a, 1, 1) tuck1: TUCKU4(stk) "\n" range(a, 1, 1) tuck1: TUCKF4(stk) "\n" range(a, 1, 1) tuck1: TUCKP4(stk) "\n" range(a, 1, 1) tuck2: TUCKI1(stk) "\n" range(a, 2, 2) tuck2: TUCKU1(stk) "\n" range(a, 2, 2) tuck2: TUCKI2(stk) "\n" range(a, 2, 2) tuck2: TUCKU2(stk) "\n" range(a, 2, 2) tuck2: TUCKI4(stk) "\n" range(a, 2, 2) tuck2: TUCKU4(stk) "\n" range(a, 2, 2) tuck2: TUCKF4(stk) "\n" range(a, 2, 2) tuck2: TUCKP4(stk) "\n" range(a, 2, 2) tuck3: TUCKI1(stk) "\n" range(a, 3, 3) tuck3: TUCKU1(stk) "\n" range(a, 3, 3) tuck3: TUCKI2(stk) "\n" range(a, 3, 3) tuck3: TUCKU2(stk) "\n" range(a, 3, 3) tuck3: TUCKI4(stk) "\n" range(a, 3, 3) tuck3: TUCKU4(stk) "\n" range(a, 3, 3) tuck3: TUCKF4(stk) "\n" range(a, 3, 3) tuck3: TUCKP4(stk) "\n" range(a, 3, 3) tuck4: TUCKI1(stk) "\n" range(a, 4, 4) tuck4: TUCKU1(stk) "\n" range(a, 4, 4) tuck4: TUCKI2(stk) "\n" range(a, 4, 4) tuck4: TUCKU2(stk) "\n" range(a, 4, 4) tuck4: TUCKI4(stk) "\n" range(a, 4, 4) tuck4: TUCKU4(stk) "\n" range(a, 4, 4) tuck4: TUCKF4(stk) "\n" range(a, 4, 4) tuck4: TUCKP4(stk) "\n" range(a, 4, 4) stk: tuck1 "copy1\n" stk: tuck2 "tuck2\n" stk: tuck3 "tuck3\n" stk: tuck4 "tuck4\n" stmt: tuck1 "\n" stmt: tuck2 "swap\n" stmt: tuck3 "rsu3\n" stmt: tuck4 "rsu4\n" stmt: ASGNI1(stk, var) "\n" stmt: ASGNU1(stk, var) "\n" stmt: ASGNI2(stk, var) "\n" stmt: ASGNU2(stk, var) "\n" stmt: ASGNF4(stk, var) "\n" stmt: ASGNI4(stk, var) "\n" stmt: ASGNP4(stk, var) "\n" stmt: ASGNU4(stk, var) "\n" var: STACKP "\n" range(a, 1, 1) var: STACKP "swap\n" range(a, 2, 2)+1 var: STACKP "rsu3\n" range(a, 3, 3)+1 var: STACKP "rsu4\n" range(a, 4, 4)+1 cnst1: CNSTI1 "" range(a, 1, 1) cnst1: CNSTU1 "" range(a, 1, 1) cnst1: CNSTI2 "" range(a, 1, 1) cnst1: CNSTU2 "" range(a, 1, 1) cnst1: CNSTI4 "" range(a, 1, 1) cnst1: CNSTU4 "" range(a, 1, 1) cnst2: CNSTI1 "" range(a, 2, 2) cnst2: CNSTU1 "" range(a, 2, 2) cnst2: CNSTI2 "" range(a, 2, 2) cnst2: CNSTU2 "" range(a, 2, 2) cnst2: CNSTI4 "" range(a, 2, 2) cnst2: CNSTU4 "" range(a, 2, 2) cnst: CNSTI1 "%a" 3 cnst: CNSTU1 "%a" 3 cnst: CNSTI2 "%a" 3 cnst: CNSTU2 "%a" 3 cnst: CNSTI4 "%a" 3 cnst: CNSTU4 "%a" 3 cnst: CNSTP4 "%a" 3 stk: cnst1 "lit 1\n" 1 stk: cnst2 "lit 2\n" 1 stk: cnst "#\n" 2 stmt: stk "drop\n" glob: ADDRGP4 "%a" local: ADDRFP4 "%a" local: ADDRLP4 "%a" stk: ADDRGP4 "lit %a\n" 2 stk: NOOP "dead\n" 0 stk: ADDRFP4 "Error - Address of parameter\n" LBURG_MAX stk: ADDRLP4 "#\n" 3 zero: CNSTI1 "" range(a, 0, 0) zero: CNSTI2 "" range(a, 0, 0) zero: CNSTI4 "" range(a, 0, 0) zero: CNSTU1 "" range(a, 0, 0) zero: CNSTU2 "" range(a, 0, 0) zero: CNSTU4 "" range(a, 0, 0) zero: CNSTP4 "" range(a, 0, 0) stmt: ASGNI1(stk, local) "#\n" 3 stmt: ASGNU1(stk, local) "#\n" 3 stmt: ASGNI2(stk, local) "#\n" 3 stmt: ASGNU2(stk, local) "#\n" 3 stmt: ASGNI4(stk, local) "#\n" 2 stmt: ASGNU4(stk, local) "#\n" 2 stmt: ASGNP4(stk, local) "#\n" 2 stmt: ASGNF4(stk, local) "#\n" 2 stmt: ASGNI1(stk, stk) "!.b\n" 3 stmt: ASGNU1(stk, stk) "!.b\n" 3 stmt: ASGNI2(stk, stk) "!.s\n" 3 stmt: ASGNU2(stk, stk) "!.s\n" 3 stmt: ASGNI4(stk, stk) "!.l\n" 3 stmt: ASGNU4(stk, stk) "!.l\n" 3 stmt: ASGNP4(stk, stk) "!.l\n" 3 stmt: ASGNF4(stk, stk) "!.l\n" 3 stk: INDIRI1(local) "#\n" 3 stk: INDIRU1(local) "#\n" 3 stk: INDIRI2(local) "#\n" 3 stk: INDIRU2(local) "#\n" 3 stk: INDIRI4(local) "#\n" 3 stk: INDIRU4(local) "#\n" 3 stk: INDIRP4(local) "#\n" 3 stk: INDIRF4(local) "#\n" 3 stk: INDIRI1(stk) "@.b\n" 2 stk: INDIRU1(stk) "@.b\nlit 255\nand\n" 5 stk: INDIRI2(stk) "@.s\n" 2 stk: INDIRU2(stk) "@.s\nlit 65535\nand\n" 5 stk: INDIRI4(stk) "@.l\n" 3 stk: INDIRU4(stk) "@.l\n" 3 stk: INDIRP4(stk) "@.l\n" 3 stk: INDIRF4(stk) "@.l\n" 3 stk: DIVI4(stk, stk) "div\n" 8 stk: DIVU4(stk, stk) "cl ___divu__\n" 10 stk: MODI4(stk, stk) "cl ___rem__\n" 8 stk: MODU4(stk, stk) "cl ___remu__\n" 10 stk: MULI4(stk, stk) "mul\n" 8 stk: MULU4(stk, stk) "mul\n" 10 stk: ADDI4(cnst1, stk) "tos++\n" 1 stk: ADDU4(cnst1, stk) "tos++\n" 1 stk: ADDP4(cnst1, stk) "tos++\n" 1 stk: ADDI4(stk, cnst1) "tos++\n" 1 stk: ADDU4(stk, cnst1) "tos++\n" 1 stk: ADDP4(stk, cnst1) "tos++\n" 1 stk: SUBI4(stk, cnst1) "tos--\n" 1 stk: SUBU4(stk, cnst1) "tos--\n" 1 stk: ADDI4(stk, stk) "add\n" 1 stk: ADDU4(stk, stk) "add\n" 1 stk: ADDP4(stk, stk) "add\n" 1 stk: ADDI4(stk, zero) "\n" stk: ADDU4(stk, zero) "\n" stk: ADDP4(stk, zero) "\n" stk: BANDI4(stk, stk) "and\n" 1 stk: BORI4(stk, stk) "or\n" 1 stk: BXORI4(stk, stk) "xor\n" 1 stk: BANDU4(stk, stk) "and\n" 1 stk: BORU4(stk, stk) "or\n" 1 stk: BXORU4(stk, stk) "xor\n" 1 stk: SUBI4(stk, stk) "sub\n" 1 stk: SUBU4(stk, stk) "sub\n" 1 stk: SUBP4(stk, stk) "sub\n" 1 stk: LSHI4(stk, cnst1) "asl\n" 1 stk: LSHU4(stk, cnst1) "asl\n" 1 stk: RSHI4(stk, cnst1) "asr\n" 1 stk: RSHU4(stk, cnst1) "shr\n" 1 stk: LSHI4(stk,stk) "basl\n" 2 stk: LSHU4(stk,stk) "basl\n" 2 stk: RSHI4(stk,stk) "basr\n" 2 stk: RSHU4(stk,stk) "bshr\n" 2 stk: BCOMI4(stk) "not\n" 1 stk: BCOMU4(stk) "not\n" 1 stk: NEGI4(stk) "not\ntos++\n" 2 stk: ADDF4(stk,stk) "fadd\n" 4 stk: DIVF4(stk,stk) "fdiv\n" 8 stk: MULF4(stk,stk) "fmul\n" 6 stk: SUBF4(stk,stk) "fsub\n" 4 stk: NEGF4(stk) "lit 1\nror\nxor\n" 3 stk: CVII1(stk) "sxbl\n" 1 stk: CVII2(stk) "sxsl\n" 1 stk: CVII4(stk) "\n" stk: CVIU1(stk) "lit 255\nand\n" 3 stk: CVIU2(stk) "lit 65535\nand\n" 3 stk: CVIU4(stk) "\n" stk: CVUI1(stk) "sxbl\n" 1 stk: CVUI2(stk) "sxwl\n" 1 stk: CVUI4(stk) "\n" stk: CVUU1(stk) "lsi 255\nand\n" 3 stk: CVUU2(stk) "lsi 65535\nand\n" 3 stk: CVUU4(stk) "\n" stk: CVFF4(stk) "\n" stk: CVIF4(stk) "itof\n" 5 stk: CVFI4(stk) "ftoi\n" 5 stk: CVPU4(stk) "\n" stk: CVUP4(stk) "\n" stmt: LABELV "%a:\n" stmt: JUMPV(glob) "bl %0\n" 1 stmt: JUMPV(stk) ">r\nexit\n" 2 stmt: EQI4(stk, stk) "teq\nbcp %a\n" 3 stmt: EQU4(stk, stk) "teq\nbcp %a\n" 3 stmt: NEI4(stk, stk) "tne\nbcp %a\n" 3 stmt: NEU4(stk, stk) "tne\nbcp %a\n" 3 stmt: GEI4(stk,stk) "tlt\nbzp %a\n" 3 stmt: GTI4(stk,stk) "tgt\nbcp %a\n" 3 stmt: LEI4(stk,stk) "tgt\nbzp %a\n" 3 stmt: LTI4(stk,stk) "tlt\nbcp %a\n" 3 stmt: EQI4(stk, zero) "bzp %a\n" 2 stmt: NEI4(stk, zero) "bcp %a\n" 2 stmt: EQU4(stk, zero) "bzp %a\n" 2 stmt: NEU4(stk, zero) "bcp %a\n" 2 stmt: GEI4(stk, zero) "tnv\nbzp %a\n" 3 stmt: LTI4(stk, zero) "tnv\nbcp %a\n" 3 stmt: GTI4(stk, zero) "bcp %a\n" 2 stmt: GEU4(stk,stk) "utlt\nbzp %a\n" 3 stmt: GTU4(stk,stk) "utgt\nbcp %a\n" 3 stmt: LEU4(stk,stk) "utgt\nbzp %a\n" 3 stmt: LTU4(stk,stk) "utlt\nbcp %a\n" 3 stmt: EQF4(stk, stk) "fteq\nbcp %a\n" 4 stmt: NEF4(stk, stk) "fteq\nbzp %a\n" 4 stmt: GEF4(stk,stk) "ftlt\nbzp %a\n" 4 stmt: GTF4(stk,stk) "ftgt\nbcp %a\n" 4 stmt: LEF4(stk,stk) "ftgt\nbzp %a\n" 4 stmt: LTF4(stk,stk) "ftlt\nbcp %a\n" 4 stk: CALLF4(glob) "#\n" 1 stk: CALLI4(glob) "#\n" 1 stk: CALLP4(glob) "#\n" 1 stk: CALLP4(glob) "#\n" 1 stk: CALLU4(glob) "#\n" 1 stmt: CALLV(glob) "#\n" 1 stmt: CALLB(glob, stk) "#\n" 4 stk: CALLF4(stk) "#\n" 5 stk: CALLI4(stk) "#\n" 5 stk: CALLP4(stk) "#\n" 5 stk: CALLP4(stk) "#\n" 5 stk: CALLU4(stk) "#\n" 5 stmt: CALLV(stk) "#\n" 5 stmt: CALLB(stk, stk) "#\n" 3 stmt: RETF4(stk) "\n" 3 stmt: RETI4(stk) "\n" 3 stmt: RETU4(stk) "\n" 3 stmt: RETP4(stk) "\n" 3 stmt: RETV "\n" 3 stmt: ARGF4(stk) "#\n" 1 stmt: ARGI4(stk) "#\n" 1 stmt: ARGP4(stk) "#\n" 1 stmt: ARGU4(stk) "#\n" 1 stmt: ASGNB(INDIRB(stk), stk) "#\n" 10 %% static void preamble(Symbol f, Symbol caller[], Symbol callee[], int ncalls); static void postamble(Symbol f, Symbol caller[], Symbol callee[], int ncalls); static int makeTemp(Symbol p) { if (!isscalar(p->type) || p->type->size == 8) { p->sclass = AUTO; return 0; } else if (p->sclass == AUTO) { if (p->addressed) { return 0; } else { makeTemporary(p); return 1; } } else if (p->sclass == REGISTER) { makeTemporary(p); return 1; } else { return 0; } } static void local(Symbol p) { if (!makeTemp(p)) { mkauto(p); } } static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { int i, size, varargs; Node params; offset = local_variable_count = 0; varargs = variadic(f->type); params = stackParameters(caller, callee); gencode(caller, callee); optimise(); framesize = roundup(offset, 4); preamble(f, caller, callee, ncalls); stackemit(params); emitcode(); postamble(f, caller, callee, ncalls); } static Node recalcNode(Node temp, Node calc) { int op = specific(calc->op); if (op == ADDRG + P) { return calc; } else if (op == CNST + I || op == CNST + U || op == CNST + P) { return calc; } else { int gop = generic(calc->op); if (gop == CVP) { if (generic(calc->kids[0]->op) == INDIR && calc->kids[0]->kids[0]->op == VREG + P) return calc; } else if (gop == INDIR && calc->kids[0]->op == VREG + P) return calc; return temp; } } static void preamble(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { Type retType = freturn(f->type); int params = 0; print("%s:\n", f->x.name); while(caller[params]) params++; // print("; %d parameters\n", params); if (variadic(f->type)) { print("cl ___utsa_variadic__\n"); } if (framesize) { print("lit %d\nfp-\n", framesize); } } static void postamble(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { if (variadic(f->type)) { print("r>\n!fp\n"); } else { if (framesize) { print("lit %d\nfp+\n", framesize); } } print("exit\n\n"); } static void structcopy(int size) { // tos = destination // nos = source assert ((size & 3) == 0); switch (size/4) { case 0: break; case 1: print("swap\n@\nswap\n!\n"); break; default: print("lit %d\ncl __copy__\n", size >> 2); } } static int call_label = 0; static int arguments = 0; static int fixedParameters(Type ty) { int i; for (i = 2; ty->u.f.proto[i]; i++); return i - 1; } static int getLocal(Symbol s) { int offset = s->x.offset + framesize; return offset; } static void printint(int i) { print("lit %d\n", i); } static void printLocal(char op, Symbol local, int size) { int index = getLocal(local); if (index < 64 && size == 4) { assert((index & 3) == 0); print("%cloc %d\n", op, index>>2); } else { char c = ((size == 4) ? 'l' : (size == 2) ? 's' : 'b'); printint(index); print("@fp\nadd\n%c.%c\n", op, c); } } static void emit2(Node p) { int op = specific(p->op); int size = opsize(p->op); if (op == INDIR + I || op == INDIR + U || op == INDIR + P || op == INDIR + F) { printLocal('@', p->kids[0]->syms[0], size); } else if (op == ASGN + I || op == ASGN + U || op == ASGN + P || op == ASGN + F) { printLocal('!', p->kids[1]->syms[0], size); } else if (op == ASGN + B) { structcopy(p->syms[0]->u.c.v.i); } else if (op == CALL + I || op == CALL + U || op == CALL + P || op == CALL + F || op == CALL + V) { if (variadic(p->syms[0]->type)) { print("lit %d\n!yp\n", arguments - fixedParameters(p->syms[0]->type)); } arguments = 0; if (generic(p->kids[0]->op) == ADDRG) { print("cl %s\n", p->kids[0]->syms[0]->x.name); } else { call_label++; print("; icall sequence\nlit ic_%d\n", call_label); print(">r\n>r\nexit\nic_%d:\n", call_label); } } else if (op == ADDRL + P) { int index = getLocal(p->syms[0]); if (index) print("@fp\nlit %d\nadd\n", index); else print("@fp\n"); } else if (op == CNST + I || op == CNST + U || op == CNST + P) { printint(p->syms[0]->u.c.v.i); } else if (op == ARG + P || op == ARG + I || op == ARG + F || op == ARG + U) { arguments++; } else { print("Error unexpected op\n"); } } union fuu { unsigned int u; float f; }; static void defconst(int suffix, int size, Value v) { if (suffix == F && size == 4) { union fuu fuu; fuu.f = v.d; unsigned u = fuu.u; print(".word %u\n", u); } else if (suffix == P) print(".word %d\n", (unsigned)v.p); else if (size == 1) print(".byte %d\n", (unsigned)((unsigned char)(suffix == I ? v.i : v.u))); else if (size == 2) print(".short %d\n", (unsigned)((unsigned short)(suffix == I ? v.i : v.u))); else if (size == 4) print(".word %d\n", (unsigned)(suffix == I ? v.i : v.u)); } static void defaddress(Symbol p) { print(".addr %s\n", p->x.name); } static void defstring(int n, char *str) { int i; for (i = 0; i < n; i++) { print(".byte %d\n", str[i]); } } static void export(Symbol p) { print(".export %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("a%d", genlabel(1)); else if (p->scope == LABELS) p->x.name = stringf("l%s", p->name); else if (p->generated) p->x.name = stringf("x%s", p->name); else if (p->temporary) p->x.name = stringf("t%s", p->name); else if (p->scope == GLOBAL) p->x.name = stringf("_%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) { // Assembler cannot handle arbitary arithmetic, so have to check for offset. int i; char c; for (i = 0; c = p->x.name[i]; i++) { if (c == '+' || c == '-') { int offset = atoi(p->x.name + i + 1); if (c == '-') offset = -offset; p->x.name[i] = '\0'; n += offset; q->x.name = stringf("%s%s%D", p->x.name, n >= 0 ? "+" : "", n); return; } } 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->type->align != 1) { print(".align %d\n", p->type->align); } print("%s:\n", p->x.name); } static void segment(int n) { switch (n) { case CODE: print(".text\n"); break; case DATA: print(".data\n"); break; case BSS: print(".data\n"); break; case LIT: print(".data\n"); break; } } static void space(int n) { print(".skip %d\n", n); } static void stabinit(char *, int, char *[]); static void stabline(Coordinate *); static void stabsym(Symbol); static char *currentfile; /* stabinit - initialize stab output */ static void stabinit(char *file, int argc, char *argv[]) { if (file) { print(".file \"%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 \"%s\"\n", cp->file); currentfile = cp->file; } print(".line %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); } static int offset_array[100]; static int *offset_stack = offset_array; static void blockbeg(Env* env) { } static void blockend(Env* env) { } static void progbeg(int argc, char *argv[]) { backendflags(argc, argv); } static void progend(void){} Interface utsaIR = { { 1, 1, 0 }, /* char_metrics */ { 2, 2, 0 }, /* short_metrics */ { 4, 4, 0 }, /* int_metrics */ { 4, 4, 0 }, /* long_metrics */ /*** TO DO - Change long long to 64 bit ***/ { 4, 4, 0 }, /* long_long_metrics */ { 4, 4, 1 }, /* float_metrics */ /*** TO DO - Change double & long double to 64 bit ***/ { 4, 4, 1 }, /* double_metrics */ { 4, 4, 1 }, /* long_double_metrics */ { 4, 4, 0 }, /* word_metrics */ { 0, 4, 0 }, /* struct_metrics */ 1, /* little_endian */ 0, /* mulops_calls */ 0, /* wants_callb */ 0, /* wants_argb */ 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ address, blockbeg, blockend, defaddress, defconst, defstring, defsymbol, stackemit, export, function, stackgen, global, import, local, progbeg, progend, segment, space, 0, 0, 0, stabinit, stabline, stabsym, 0, swtch, { 1, /* max_unaligned_load */ 2, recalcNode, makeTemp, NULL, _label, _rule, _nts, _kids, _string, _templates, _isinstruction, _ntname, emit2, { 0, // sub 0, // lsh 0, // rsh 0, // mod 0, // div 0, // lt 0, // le 0, // gt 0 // ge } } };