Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

x86linux.md (32427B)


      1 %{
      2 /* x86/linux lburg spec. Derived from x86.md by
      3 Marcos Ramirez <marcos@inf.utfsm.cl>
      4 Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
      5 Jacob Navia <jacob@jacob.remcomp.fr>
      6 */
      7 enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 };
      8 #include "c.h"
      9 #define NODEPTR_TYPE Node
     10 #define OP_LABEL(p) ((p)->op)
     11 #define LEFT_CHILD(p) ((p)->kids[0])
     12 #define RIGHT_CHILD(p) ((p)->kids[1])
     13 #define STATE_LABEL(p) ((p)->x.state)
     14 extern int ckstack(Node, int);
     15 extern int memop(Node);
     16 extern int sametree(Node, Node);
     17 static Symbol charreg[32], shortreg[32], intreg[32];
     18 static Symbol fltreg[32];
     19 
     20 static Symbol charregw, shortregw, intregw, fltregw;
     21 
     22 static int cseg;
     23 
     24 static Symbol quo, rem;
     25 
     26 extern char *stabprefix;
     27 extern void stabblock(int, int, Symbol*);
     28 extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *);
     29 extern void stabfend(Symbol, int);
     30 extern void stabinit(char *, int, char *[]);
     31 extern void stabline(Coordinate *);
     32 extern void stabsym(Symbol);
     33 extern void stabtype(Symbol);
     34 
     35 static int pflag = 0;
     36 static char rcsid[] = "$Id: x86linux.md 145 2001-10-17 21:53:10Z timo $";
     37 
     38 #define hasargs(p) (p->syms[0] && p->syms[0]->u.c.v.i > 0 ? 0 : LBURG_MAX)
     39 %}
     40 %start stmt
     41 %term CNSTF4=4113
     42 %term CNSTF8=8209
     43 %term CNSTF16=16401
     44 %term CNSTI1=1045
     45 %term CNSTI2=2069
     46 %term CNSTI4=4117
     47 %term CNSTI8=8213
     48 %term CNSTP4=4119
     49 %term CNSTP8=8215
     50 %term CNSTU1=1046
     51 %term CNSTU2=2070
     52 %term CNSTU4=4118
     53 %term CNSTU8=8214
     54  
     55 %term ARGB=41
     56 %term ARGF4=4129
     57 %term ARGF8=8225
     58 %term ARGF16=16417
     59 %term ARGI4=4133
     60 %term ARGI8=8229
     61 %term ARGP4=4135
     62 %term ARGP8=8231
     63 %term ARGU4=4134
     64 %term ARGU8=8230
     65 
     66 %term ASGNB=57
     67 %term ASGNF4=4145
     68 %term ASGNF8=8241
     69 %term ASGNF16=16433
     70 %term ASGNI1=1077
     71 %term ASGNI2=2101
     72 %term ASGNI4=4149
     73 %term ASGNI8=8245
     74 %term ASGNP4=4151
     75 %term ASGNP8=8247
     76 %term ASGNU1=1078
     77 %term ASGNU2=2102
     78 %term ASGNU4=4150
     79 %term ASGNU8=8246
     80 
     81 %term INDIRB=73
     82 %term INDIRF4=4161
     83 %term INDIRF8=8257
     84 %term INDIRF16=16449
     85 %term INDIRI1=1093
     86 %term INDIRI2=2117
     87 %term INDIRI4=4165
     88 %term INDIRI8=8261
     89 %term INDIRP4=4167
     90 %term INDIRP8=8263
     91 %term INDIRU1=1094
     92 %term INDIRU2=2118
     93 %term INDIRU4=4166
     94 %term INDIRU8=8262
     95 
     96 %term CVFF4=4209
     97 %term CVFF8=8305
     98 %term CVFF16=16497
     99 %term CVFI4=4213
    100 %term CVFI8=8309
    101 
    102 %term CVIF4=4225
    103 %term CVIF8=8321
    104 %term CVIF16=16513
    105 %term CVII1=1157
    106 %term CVII2=2181
    107 %term CVII4=4229
    108 %term CVII8=8325
    109 %term CVIU1=1158
    110 %term CVIU2=2182
    111 %term CVIU4=4230
    112 %term CVIU8=8326
    113 
    114 %term CVPP4=4247
    115 %term CVPP8=8343
    116 %term CVPP16=16535
    117 %term CVPU4=4246
    118 %term CVPU8=8342
    119 
    120 %term CVUI1=1205
    121 %term CVUI2=2229
    122 %term CVUI4=4277
    123 %term CVUI8=8373
    124 %term CVUP4=4279
    125 %term CVUP8=8375
    126 %term CVUP16=16567
    127 %term CVUU1=1206
    128 %term CVUU2=2230
    129 %term CVUU4=4278
    130 %term CVUU8=8374
    131 
    132 %term NEGF4=4289
    133 %term NEGF8=8385
    134 %term NEGF16=16577
    135 %term NEGI4=4293
    136 %term NEGI8=8389
    137 
    138 %term CALLB=217
    139 %term CALLF4=4305
    140 %term CALLF8=8401
    141 %term CALLF16=16593
    142 %term CALLI4=4309
    143 %term CALLI8=8405
    144 %term CALLP4=4311
    145 %term CALLP8=8407
    146 %term CALLU4=4310
    147 %term CALLU8=8406
    148 %term CALLV=216
    149 
    150 %term RETF4=4337
    151 %term RETF8=8433
    152 %term RETF16=16625
    153 %term RETI4=4341
    154 %term RETI8=8437
    155 %term RETP4=4343
    156 %term RETP8=8439
    157 %term RETU4=4342
    158 %term RETU8=8438
    159 %term RETV=248
    160 
    161 %term ADDRGP4=4359
    162 %term ADDRGP8=8455
    163 
    164 %term ADDRFP4=4375
    165 %term ADDRFP8=8471
    166 
    167 %term ADDRLP4=4391
    168 %term ADDRLP8=8487
    169 
    170 %term ADDF4=4401
    171 %term ADDF8=8497
    172 %term ADDF16=16689
    173 %term ADDI4=4405
    174 %term ADDI8=8501
    175 %term ADDP4=4407
    176 %term ADDP8=8503
    177 %term ADDU4=4406
    178 %term ADDU8=8502
    179 
    180 %term SUBF4=4417
    181 %term SUBF8=8513
    182 %term SUBF16=16705
    183 %term SUBI4=4421
    184 %term SUBI8=8517
    185 %term SUBP4=4423
    186 %term SUBP8=8519
    187 %term SUBU4=4422
    188 %term SUBU8=8518
    189 
    190 %term LSHI4=4437
    191 %term LSHI8=8533
    192 %term LSHU4=4438
    193 %term LSHU8=8534
    194 
    195 %term MODI4=4453
    196 %term MODI8=8549
    197 %term MODU4=4454
    198 %term MODU8=8550
    199 
    200 %term RSHI4=4469
    201 %term RSHI8=8565
    202 %term RSHU4=4470
    203 %term RSHU8=8566
    204 
    205 %term BANDI4=4485
    206 %term BANDI8=8581
    207 %term BANDU4=4486
    208 %term BANDU8=8582
    209 
    210 %term BCOMI4=4501
    211 %term BCOMI8=8597
    212 %term BCOMU4=4502
    213 %term BCOMU8=8598
    214 
    215 %term BORI4=4517
    216 %term BORI8=8613
    217 %term BORU4=4518
    218 %term BORU8=8614
    219 
    220 %term BXORI4=4533
    221 %term BXORI8=8629
    222 %term BXORU4=4534
    223 %term BXORU8=8630
    224 
    225 %term DIVF4=4545
    226 %term DIVF8=8641
    227 %term DIVF16=16833
    228 %term DIVI4=4549
    229 %term DIVI8=8645
    230 %term DIVU4=4550
    231 %term DIVU8=8646
    232 
    233 %term MULF4=4561
    234 %term MULF8=8657
    235 %term MULF16=16849
    236 %term MULI4=4565
    237 %term MULI8=8661
    238 %term MULU4=4566
    239 %term MULU8=8662
    240 
    241 %term EQF4=4577
    242 %term EQF8=8673
    243 %term EQF16=16865
    244 %term EQI4=4581
    245 %term EQI8=8677
    246 %term EQU4=4582
    247 %term EQU8=8678
    248 
    249 %term GEF4=4593
    250 %term GEF8=8689
    251 %term GEI4=4597
    252 %term GEI8=8693
    253 %term GEI16=16885
    254 %term GEU4=4598
    255 %term GEU8=8694
    256 
    257 %term GTF4=4609
    258 %term GTF8=8705
    259 %term GTF16=16897
    260 %term GTI4=4613
    261 %term GTI8=8709
    262 %term GTU4=4614
    263 %term GTU8=8710
    264 
    265 %term LEF4=4625
    266 %term LEF8=8721
    267 %term LEF16=16913
    268 %term LEI4=4629
    269 %term LEI8=8725
    270 %term LEU4=4630
    271 %term LEU8=8726
    272 
    273 %term LTF4=4641
    274 %term LTF8=8737
    275 %term LTF16=16929
    276 %term LTI4=4645
    277 %term LTI8=8741
    278 %term LTU4=4646
    279 %term LTU8=8742
    280 
    281 %term NEF4=4657
    282 %term NEF8=8753
    283 %term NEF16=16945
    284 %term NEI4=4661
    285 %term NEI8=8757
    286 %term NEU4=4662
    287 %term NEU8=8758
    288 
    289 %term JUMPV=584
    290 
    291 %term LABELV=600
    292 
    293 %term LOADB=233
    294 %term LOADF4=4321
    295 %term LOADF8=8417
    296 %term LOADF16=16609
    297 %term LOADI1=1253
    298 %term LOADI2=2277
    299 %term LOADI4=4325
    300 %term LOADI8=8421
    301 %term LOADP4=4327
    302 %term LOADP8=8423
    303 %term LOADU1=1254
    304 %term LOADU2=2278
    305 %term LOADU4=4326
    306 %term LOADU8=8422
    307 
    308 %term VREGP=711
    309 %%
    310 reg:  INDIRI1(VREGP)     "# read register\n"
    311 reg:  INDIRU1(VREGP)     "# read register\n"
    312 
    313 reg:  INDIRI2(VREGP)     "# read register\n"
    314 reg:  INDIRU2(VREGP)     "# read register\n"
    315 
    316 reg:  INDIRI4(VREGP)     "# read register\n"
    317 reg:  INDIRP4(VREGP)     "# read register\n"
    318 reg:  INDIRU4(VREGP)     "# read register\n"
    319 
    320 reg:  INDIRI8(VREGP)     "# read register\n"
    321 reg:  INDIRP8(VREGP)     "# read register\n"
    322 reg:  INDIRU8(VREGP)     "# read register\n"
    323 
    324 freg:  INDIRF4(VREGP)     "# read register\n"
    325 freg:  INDIRF8(VREGP)     "# read register\n"
    326 
    327 stmt: ASGNI1(VREGP,reg)  "# write register\n"
    328 stmt: ASGNU1(VREGP,reg)  "# write register\n"
    329 
    330 stmt: ASGNI2(VREGP,reg)  "# write register\n"
    331 stmt: ASGNU2(VREGP,reg)  "# write register\n"
    332 
    333 stmt: ASGNF4(VREGP,reg)  "# write register\n"
    334 stmt: ASGNI4(VREGP,reg)  "# write register\n"
    335 stmt: ASGNP4(VREGP,reg)  "# write register\n"
    336 stmt: ASGNU4(VREGP,reg)  "# write register\n"
    337 
    338 stmt: ASGNF8(VREGP,reg)  "# write register\n"
    339 stmt: ASGNI8(VREGP,reg)  "# write register\n"
    340 stmt: ASGNP8(VREGP,reg)  "# write register\n"
    341 stmt: ASGNU8(VREGP,reg)  "# write register\n"
    342 
    343 cnst: CNSTI1    "%a"
    344 cnst: CNSTU1    "%a"
    345 
    346 cnst: CNSTI2    "%a"
    347 cnst: CNSTU2    "%a"
    348 
    349 cnst: CNSTI4    "%a"
    350 cnst: CNSTU4    "%a"
    351 cnst: CNSTP4    "%a"
    352 
    353 cnst: CNSTI8    "%a"
    354 cnst: CNSTU8    "%a"
    355 cnst: CNSTP8    "%a"
    356 
    357 con: cnst       "$%0"
    358 
    359 stmt: reg       ""
    360 stmt: freg      ""
    361 
    362 acon: ADDRGP4  "%a"
    363 acon: ADDRGP8  "%a"
    364 acon: cnst       "%0"
    365 
    366 baseaddr: ADDRGP4       "%a"
    367 base: reg               "(%0)"
    368 base: ADDI4(reg,acon)   "%1(%0)"
    369 base: ADDP4(reg,acon)   "%1(%0)"
    370 base: ADDU4(reg,acon)   "%1(%0)"
    371 base: ADDRFP4           "%a(%%ebp)"
    372 base: ADDRLP4           "%a(%%ebp)"
    373 
    374 index: reg              "%0"
    375 index: LSHI4(reg,con1)  "%0,2"
    376 index: LSHI4(reg,con2)  "%0,4"
    377 index: LSHI4(reg,con3)  "%0,8"
    378 index: LSHU4(reg,con1)  "%0,2"
    379 index: LSHU4(reg,con2)  "%0,4"
    380 index: LSHU4(reg,con3)  "%0,8"
    381 
    382 con0:  CNSTI4  "1"  range(a, 0, 0)
    383 con0:  CNSTU4  "1"  range(a, 0, 0)
    384 con1:  CNSTI4  "1"  range(a, 1, 1)
    385 con1:  CNSTU4  "1"  range(a, 1, 1)
    386 con2:  CNSTI4  "2"  range(a, 2, 2)
    387 con2:  CNSTU4  "2"  range(a, 2, 2)
    388 con3:  CNSTI4  "3"  range(a, 3, 3)
    389 con3:  CNSTU4  "3"  range(a, 3, 3)
    390 
    391 addr: base                      "%0"
    392 addr: baseaddr                  "%0"
    393 addr: ADDI4(index,baseaddr)     "%1(,%0)"
    394 addr: ADDP4(index,baseaddr)     "%1(,%0)"
    395 addr: ADDU4(index,baseaddr)     "%1(,%0)"
    396 
    397 addr: ADDI4(reg,baseaddr)       "%1(%0)"
    398 addr: ADDP4(reg,baseaddr)       "%1(%0)"
    399 addr: ADDU4(reg,baseaddr)       "%1(%0)"
    400 
    401 addr: ADDI4(index,reg)          "(%1,%0)"
    402 addr: ADDP4(index,reg)          "(%1,%0)"
    403 addr: ADDU4(index,reg)          "(%1,%0)"
    404 
    405 addr: index  "(,%0)"
    406 
    407 mem1: INDIRI1(addr)  "%0"
    408 mem1: INDIRU1(addr)  "%0"
    409 mem2: INDIRI2(addr)  "%0"
    410 mem2: INDIRU2(addr)  "%0"
    411 mem4: INDIRI4(addr)  "%0"
    412 mem4: INDIRU4(addr)  "%0"
    413 mem4: INDIRP4(addr)  "%0"
    414 
    415 rc: reg         "%0"
    416 rc: con         "%0"
    417 
    418 mr: reg         "%0"
    419 mr: mem4        "%0"
    420 
    421 mr1: reg        "%0"
    422 mr1: mem1       "%0"
    423 
    424 mr2: reg        "%0"
    425 mr2: mem2       "%0"
    426 
    427 mrc: mem4       "%0"  1
    428 mrc: mem1       "%0"  1
    429 mrc: mem2       "%0"  1
    430 mrc: rc         "%0"
    431 
    432 reg: addr       "leal %0,%c\n"  1
    433 reg: mr         "movl %0,%c\n"  1
    434 reg: mr1        "movb %0,%c\n"  1
    435 reg: mr2        "movw %0,%c\n"  1
    436 reg: con        "movl %0,%c\n"  1
    437 
    438 reg: LOADI1(reg)        "# move\n"  1
    439 reg: LOADI2(reg)        "# move\n"  1
    440 reg: LOADI4(reg)        "# move\n"  move(a)
    441 reg: LOADU1(reg)        "# move\n"  1
    442 reg: LOADU2(reg)        "# move\n"  1
    443 reg: LOADU4(reg)        "# move\n"  move(a)
    444 reg: LOADP4(reg)        "# move\n"  move(a)
    445 reg: ADDI4(reg,mrc)     "?movl %0,%c\naddl %1,%c\n"  1
    446 reg: ADDP4(reg,mrc)     "?movl %0,%c\naddl %1,%c\n"  1
    447 reg: ADDU4(reg,mrc)     "?movl %0,%c\naddl %1,%c\n"  1
    448 reg: SUBI4(reg,mrc)     "?movl %0,%c\nsubl %1,%c\n"  1
    449 reg: SUBP4(reg,mrc)     "?movl %0,%c\nsubl %1,%c\n"  1
    450 reg: SUBU4(reg,mrc)     "?movl %0,%c\nsubl %1,%c\n"  1
    451 reg: BANDI4(reg,mrc)    "?movl %0,%c\nandl %1,%c\n"  1
    452 reg: BORI4(reg,mrc)     "?movl %0,%c\norl %1,%c\n"   1
    453 reg: BXORI4(reg,mrc)    "?movl %0,%c\nxorl %1,%c\n"  1
    454 reg: BANDU4(reg,mrc)    "?movl %0,%c\nandl %1,%c\n"  1
    455 reg: BORU4(reg,mrc)     "?movl %0,%c\norl %1,%c\n"   1
    456 reg: BXORU4(reg,mrc)    "?movl %0,%c\nxorl %1,%c\n"  1
    457 
    458 stmt: ASGNI4(addr,ADDI4(mem4,con1))     "incl %1\n"  memop(a)
    459 stmt: ASGNI4(addr,ADDU4(mem4,con1))     "incl %1\n"  memop(a)
    460 stmt: ASGNP4(addr,ADDP4(mem4,con1))     "incl %1\n"  memop(a)
    461 stmt: ASGNI4(addr,SUBI4(mem4,con1))     "decl %1\n"  memop(a)
    462 stmt: ASGNI4(addr,SUBU4(mem4,con1))     "decl %1\n"  memop(a)
    463 stmt: ASGNP4(addr,SUBP4(mem4,con1))     "decl %1\n"  memop(a)
    464 stmt: ASGNI4(addr,ADDI4(mem4,rc))       "addl %2,%1\n"  memop(a)
    465 stmt: ASGNI4(addr,SUBI4(mem4,rc))       "sub %2,%1\n"  memop(a)
    466 stmt: ASGNU4(addr,ADDU4(mem4,rc))       "add %2,%1\n"  memop(a)
    467 stmt: ASGNU4(addr,SUBU4(mem4,rc))       "sub %2,%1\n"  memop(a)
    468 
    469 stmt: ASGNI4(addr,BANDI4(mem4,rc))      "andl %2,%1\n"  memop(a)
    470 stmt: ASGNI4(addr,BORI4(mem4,rc))       "orl %2,%1\n"   memop(a)
    471 stmt: ASGNI4(addr,BXORI4(mem4,rc))      "xorl %2,%1\n"  memop(a)
    472 stmt: ASGNU4(addr,BANDU4(mem4,rc))      "andl %2,%1\n"  memop(a)
    473 stmt: ASGNU4(addr,BORU4(mem4,rc))       "orl %2,%1\n"   memop(a)
    474 stmt: ASGNU4(addr,BXORU4(mem4,rc))      "xorl %2,%1\n"  memop(a)
    475 reg: BCOMI4(reg)        "?movl %0,%c\nnotl %c\n"  2
    476 reg: BCOMU4(reg)        "?movl %0,%c\nnotl %c\n"  2
    477 reg: NEGI4(reg)         "?movl %0,%c\nnegl %c\n"  2
    478 
    479 stmt: ASGNI4(addr,BCOMI4(mem4)) "notl %1\n"  memop(a)
    480 stmt: ASGNU4(addr,BCOMU4(mem4)) "notl %1\n"  memop(a)
    481 stmt: ASGNI4(addr,NEGI4(mem4))  "negl %1\n"  memop(a)
    482 reg: LSHI4(reg,rc5)     "?movl %0,%c\nsall %1,%c\n"  2
    483 reg: LSHU4(reg,rc5)     "?movl %0,%c\nshll %1,%c\n"  2
    484 reg: RSHI4(reg,rc5)     "?movl %0,%c\nsarl %1,%c\n"  2
    485 reg: RSHU4(reg,rc5)     "?movl %0,%c\nshrl %1,%c\n"  2
    486 
    487 stmt: ASGNI4(addr,LSHI4(mem4,rc5))      "sall %2,%1\n"  memop(a)
    488 stmt: ASGNI4(addr,LSHU4(mem4,rc5))      "shll %2,%1\n"  memop(a)
    489 stmt: ASGNI4(addr,RSHI4(mem4,rc5))      "sarl %2,%1\n"  memop(a)
    490 stmt: ASGNI4(addr,RSHU4(mem4,rc5))      "shrl %2,%1\n"  memop(a)
    491 
    492 rc5: CNSTI4     "$%a"  range(a, 0, 31)
    493 rc5: reg        "%%cl"
    494 reg: MULI4(reg,mrc)     "?movl %0,%c\nimull %1,%c\n"  14
    495 reg: MULI4(con,mr)      "imul %0,%1,%c\n"  13
    496 reg: MULU4(reg,mr)      "mull %1\n"  13
    497 reg: DIVU4(reg,reg)     "xorl %%edx,%%edx\ndivl %1\n"
    498 reg: MODU4(reg,reg)     "xorl %%edx,%%edx\ndivl %1\n"
    499 reg: DIVI4(reg,reg)     "cdq\nidivl %1\n"
    500 reg: MODI4(reg,reg)     "cdq\nidivl %1\n"
    501 reg: CVPU4(reg)         "movl %0,%c\n"  move(a)
    502 reg: CVUP4(reg)         "movl %0,%c\n"  move(a)
    503 reg: CVII4(INDIRI1(addr))       "movsbl %0,%c\n"  3
    504 reg: CVII4(INDIRI2(addr))       "movswl %0,%c\n"  3
    505 reg: CVUU4(INDIRU1(addr))       "movzbl %0,%c\n"  3
    506 reg: CVUU4(INDIRU2(addr))       "movzwl %0,%c\n"  3
    507 reg: CVII4(reg) "# extend\n"  3
    508 reg: CVIU4(reg) "# extend\n"  3
    509 reg: CVUI4(reg) "# extend\n"  3
    510 reg: CVUU4(reg) "# extend\n"  3
    511 
    512 reg: CVII1(reg) "# truncate\n"  1
    513 reg: CVII2(reg) "# truncate\n"  1
    514 reg: CVUU1(reg) "# truncate\n"  1
    515 reg: CVUU2(reg) "# truncate\n"  1
    516 
    517 mrca: mem4      "%0"
    518 mrca: rc        "%0"
    519 mrca: ADDRGP4   "$%a"
    520 mrca: ADDRGP8   "$%a"
    521 
    522 stmt: ASGNI1(addr,rc)           "movb %1,%0\n"   1
    523 stmt: ASGNI2(addr,rc)           "movw %1,%0\n"   1
    524 stmt: ASGNI4(addr,rc)           "movl %1,%0\n"   1
    525 stmt: ASGNU1(addr,rc)           "movb %1,%0\n"   1
    526 stmt: ASGNU2(addr,rc)           "movw %1,%0\n"   1
    527 stmt: ASGNU4(addr,rc)           "movl %1,%0\n"   1
    528 stmt: ASGNP4(addr,rc)           "movl %1,%0\n"   1
    529 stmt: ARGI4(mrca)               "pushl %0\n"  1
    530 stmt: ARGU4(mrca)               "pushl %0\n"  1
    531 stmt: ARGP4(mrca)               "pushl %0\n"  1
    532 stmt: ASGNB(reg,INDIRB(reg))    "movl $%a,%%ecx\nrep\nmovsb\n"
    533 stmt: ARGB(INDIRB(reg))         "subl $%a,%%esp\nmovl %%esp,%%edi\nmovl $%a,%%ecx\nrep\nmovsb\n"
    534 
    535 memf: INDIRF8(addr)         "l %0"
    536 memf: INDIRF4(addr)         "s %0"
    537 memf: CVFF8(INDIRF4(addr))  "s %0"
    538 memf: CVFF4(INDIRF8(addr))  "l %0"
    539 
    540 freg: memf      "fld%0\n"  3
    541 
    542 stmt: ASGNF8(addr,freg)         "fstpl %0\n"  7
    543 stmt: ASGNF4(addr,freg)         "fstps %0\n"  7
    544 stmt: ASGNF4(addr,CVFF4(freg))  "fstps %0\n"  7
    545 
    546 stmt: ARGF8(freg)       "subl $8,%%esp\nfstpl (%%esp)\n"
    547 stmt: ARGF4(freg)       "subl $4,%%esp\nfstps (%%esp)\n"
    548 freg: NEGF8(freg)       "fchs\n"
    549 freg: NEGF4(freg)       "fchs\n"
    550 
    551 flt: memf       "%0"
    552 flt: freg       "p %%st(1),%%st"
    553 
    554 freg: ADDF4(freg,flt)   "fadd%1\n"
    555 freg: ADDF8(freg,flt)   "fadd%1\n"
    556 
    557 freg: DIVF4(freg,flt)   "fdiv%1\n"
    558 freg: DIVF8(freg,flt)   "fdiv%1\n"
    559 
    560 freg: MULF4(freg,flt)   "fmul%1\n"
    561 freg: MULF8(freg,flt)   "fmul%1\n"
    562 
    563 freg: SUBF4(freg,flt)   "fsub%1\n"
    564 freg: SUBF8(freg,flt)   "fsub%1\n"
    565 
    566 freg: CVFF8(freg)  "# CVFF8\n"
    567 freg: CVFF4(freg)  "sub $4,%%esp\nfstps (%%esp)\nflds (%%esp)\naddl $4,%%esp\n"  12
    568 
    569 stmt: ASGNI4(addr,CVFI4(freg))  "fistpl %0\n" 29
    570 reg: CVFI4(freg)  "subl $4,%%esp\nfistpl 0(%%esp)\npopl %c\n" 31
    571 
    572 freg: CVIF8(INDIRI4(addr))      "fildl %0\n"  10
    573 freg: CVIF8(reg)  "pushl %0\nfildl (%%esp)\naddl $4,%%esp\n"  12
    574 
    575 freg: CVIF4(INDIRI4(addr))      "fildl %0\n"  10
    576 freg: CVIF4(reg)  "pushl %0\nfildl (%%esp)\naddl $4,%%esp\n"  12
    577 
    578 addrj: ADDRGP4  "%a"
    579 addrj: reg      "*%0"  2
    580 addrj: mem4     "*%0"  2
    581 
    582 stmt: LABELV         "%a:\n"
    583 stmt: JUMPV(addrj)   "jmp %0\n"  3
    584 stmt: EQI4(mem4,rc)  "cmpl %1,%0\nje %a\n"   5
    585 stmt: GEI4(mem4,rc)  "cmpl %1,%0\njge %a\n"  5
    586 stmt: GTI4(mem4,rc)  "cmpl %1,%0\njg %a\n"   5
    587 stmt: LEI4(mem4,rc)  "cmpl %1,%0\njle %a\n"  5
    588 stmt: LTI4(mem4,rc)  "cmpl %1,%0\njl %a\n"   5
    589 stmt: NEI4(mem4,rc)  "cmpl %1,%0\njne %a\n"  5
    590 stmt: GEU4(mem4,rc)  "cmpl %1,%0\njae %a\n"  5
    591 stmt: GTU4(mem4,rc)  "cmpl %1,%0\nja  %a\n"  5
    592 stmt: LEU4(mem4,rc)  "cmpl %1,%0\njbe %a\n"  5
    593 stmt: LTU4(mem4,rc)  "cmpl %1,%0\njb  %a\n"  5
    594 stmt: EQI4(reg,mrc)  "cmpl %1,%0\nje %a\n"   4
    595 stmt: GEI4(reg,mrc)  "cmpl %1,%0\njge %a\n"  4
    596 stmt: GTI4(reg,mrc)  "cmpl %1,%0\njg %a\n"   4
    597 stmt: LEI4(reg,mrc)  "cmpl %1,%0\njle %a\n"  4
    598 stmt: LTI4(reg,mrc)  "cmpl %1,%0\njl %a\n"   4
    599 stmt: NEI4(reg,mrc)  "cmpl %1,%0\njne %a\n"  4
    600 
    601 stmt: EQU4(reg,mrc)  "cmpl %1,%0\nje %a\n"   4
    602 stmt: GEU4(reg,mrc)  "cmpl %1,%0\njae %a\n"  4
    603 stmt: GTU4(reg,mrc)  "cmpl %1,%0\nja %a\n"   4
    604 stmt: LEU4(reg,mrc)  "cmpl %1,%0\njbe %a\n"  4
    605 stmt: LTU4(reg,mrc)  "cmpl %1,%0\njb %a\n"   4
    606 stmt: NEU4(reg,mrc)  "cmpl %1,%0\njne %a\n"  4
    607 
    608 stmt: EQI4(BANDU4(mr,con),con0) "testl %1,%0\nje %a\n" 3
    609 stmt: NEI4(BANDU4(mr,con),con0) "testl %1,%0\njne %a\n"
    610 
    611 stmt: EQI4(BANDU4(CVII2(INDIRI2(addr)),con),con0) "testw %1,%0\nje %a\n"
    612 stmt: NEI4(BANDU4(CVII2(INDIRI2(addr)),con),con0) "testw %1,%0\njne %a\n"
    613 stmt: EQI4(BANDU4(CVIU2(INDIRI2(addr)),con),con0) "testw %1,%0\nje %a\n"
    614 stmt: NEI4(BANDU4(CVIU2(INDIRI2(addr)),con),con0) "testw %1,%0\njne %a\n"
    615 stmt: EQI4(BANDU4(CVII1(INDIRI1(addr)),con),con0) "testb %1,%0\nje %a\n"
    616 
    617 cmpf: INDIRF8(addr)             "l %0"
    618 cmpf: INDIRF4(addr)             "s %0"
    619 cmpf: CVFF8(INDIRF4(addr))      "s %0"
    620 cmpf: freg                      "p"
    621 
    622 stmt: EQF8(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\nje %a\n"
    623 stmt: GEF8(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\njbe %a\n"
    624 stmt: GTF8(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\njb %a\n"
    625 stmt: LEF8(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\njae %a\n"
    626 stmt: LTF8(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\nja %a\n"
    627 stmt: NEF8(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\njne %a\n"
    628 
    629 stmt: EQF4(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\nje %a\n"
    630 stmt: GEF4(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\njbe %a\n"
    631 stmt: GTF4(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\njb %a\n"
    632 stmt: LEF4(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\njae %a\n"
    633 stmt: LTF4(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\nja %a\n"
    634 stmt: NEF4(cmpf,freg)  "fcomp%0\nfstsw %%ax\nsahf\njne %a\n"
    635 
    636 freg: DIVF8(freg,CVIF8(INDIRI4(addr)))          "fidivl %1\n"
    637 freg: DIVF8(CVIF8(INDIRI4(addr)),freg)          "fidivrl %0\n"
    638 freg: DIVF8(freg,CVIF8(CVII2(INDIRI2(addr))))   "fidivs %1\n"
    639 freg: DIVF8(CVIF8(CVII2(INDIRI2(addr))),freg)   "fidivrs %0\n"
    640 freg: MULF8(freg,CVIF8(INDIRI4(addr)))          "fimull %1\n"
    641 freg: MULF8(freg,CVIF8(CVII2(INDIRI2(addr))))   "fimuls %1\n"
    642 freg: SUBF8(freg,CVIF8(INDIRI4(addr)))          "fisubl %1\n"
    643 freg: SUBF8(CVIF8(INDIRI4(addr)),freg)          "fisubrl %0\n"
    644 freg: SUBF8(freg,CVIF8(CVII2(INDIRI2(addr))))   "fisubs %1\n"
    645 freg: SUBF8(CVIF8(CVII2(INDIRI2(addr))),freg)   "fisubrs %0\n"
    646 freg: ADDF8(freg,CVIF8(INDIRI4(addr)))          "fiaddl %1\n"
    647 freg: ADDF8(freg,CVIF8(CVII2(INDIRI2(addr))))   "fiadds %1\n"
    648 freg: ADDF8(freg,CVFF8(INDIRF4(addr)))          "fdivs %1\n"
    649 freg: SUBF8(freg,CVFF8(INDIRF4(addr)))          "fsubs %1\n"
    650 freg: MULF8(freg,CVFF8(INDIRF4(addr)))          "fmuls %1\n"
    651 freg: DIVF8(freg,CVFF8(INDIRF4(addr)))          "fdivs %1\n"
    652 freg: LOADF8(memf)                              "fld%0\n"
    653 
    654 reg:  CALLI4(addrj)  "call %0\naddl $%a,%%esp\n"        hasargs(a)
    655 reg:  CALLU4(addrj)  "call %0\naddl $%a,%%esp\n"        hasargs(a)
    656 reg:  CALLP4(addrj)  "call %0\naddl $%a,%%esp\n"        hasargs(a)
    657 
    658 reg:  CALLI4(addrj)  "call %0\n"                        1
    659 reg:  CALLU4(addrj)  "call %0\n"                        1
    660 reg:  CALLP4(addrj)  "call %0\n"                        1
    661 
    662 stmt: CALLV(addrj)   "call %0\naddl $%a,%%esp\n"        hasargs(a)
    663 stmt: CALLV(addrj)   "call %0\n"                        1
    664 
    665 freg: CALLF4(addrj)  "call %0\naddl $%a,%%esp\n"        hasargs(a)
    666 freg: CALLF4(addrj)  "call %0\n"                        1
    667 
    668 stmt: CALLF4(addrj)  "call %0\naddl $%a,%%esp\nfstp %%st(0)\n"  hasargs(a)
    669 stmt: CALLF4(addrj)  "call %0\nfstp %%st(0)\n"                  1
    670 
    671 freg: CALLF8(addrj)  "call %0\naddl $%a,%%esp\n"        hasargs(a)
    672 freg: CALLF8(addrj)  "call %0\n"                        1
    673 
    674 stmt: CALLF8(addrj)  "call %0\naddl $%a,%%esp\nfstp %%st(0)\n"  hasargs(a)
    675 stmt: CALLF8(addrj)  "call %0\nfstp %%st(0)\n"                  1
    676 
    677 stmt: RETI4(reg)  "# ret\n"
    678 stmt: RETU4(reg)  "# ret\n"
    679 stmt: RETP4(reg)  "# ret\n"
    680 stmt: RETF4(freg) "# ret\n"
    681 stmt: RETF8(freg) "# ret\n"
    682 %%
    683 static void progbeg(int argc, char *argv[]) {
    684         int i;
    685 
    686         {
    687                 union {
    688                         char c;
    689                         int i;
    690                 } u;
    691                 u.i = 0;
    692                 u.c = 1;
    693                 swap = ((int)(u.i == 1)) != IR->little_endian;
    694         }
    695         parseflags(argc, argv);
    696         for (i = 0; i < argc; i++)
    697                 if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-pg") == 0)
    698                         pflag = 1;      
    699         intreg[EAX]   = mkreg("%%eax", EAX, 1, IREG);
    700         intreg[EDX]   = mkreg("%%edx", EDX, 1, IREG);
    701         intreg[ECX]   = mkreg("%%ecx", ECX, 1, IREG);
    702         intreg[EBX]   = mkreg("%%ebx", EBX, 1, IREG);
    703         intreg[ESI]   = mkreg("%%esi", ESI, 1, IREG);
    704         intreg[EDI]   = mkreg("%%edi", EDI, 1, IREG);
    705         shortreg[EAX] = mkreg("%%ax", EAX, 1, IREG);
    706         shortreg[ECX] = mkreg("%%cx", ECX, 1, IREG);
    707         shortreg[EDX] = mkreg("%%dx", EDX, 1, IREG);
    708         shortreg[EBX] = mkreg("%%bx", EBX, 1, IREG);
    709         shortreg[ESI] = mkreg("%%si", ESI, 1, IREG);
    710         shortreg[EDI] = mkreg("%%di", EDI, 1, IREG);
    711         charreg[EAX]  = mkreg("%%al", EAX, 1, IREG);
    712         charreg[ECX]  = mkreg("%%cl", ECX, 1, IREG);
    713         charreg[EDX]  = mkreg("%%dl", EDX, 1, IREG);
    714         charreg[EBX]  = mkreg("%%bl", EBX, 1, IREG);
    715         for (i = 0; i < 8; i++)
    716                 fltreg[i] = mkreg("%d", i, 0, FREG);
    717         charregw = mkwildcard(charreg);
    718         shortregw = mkwildcard(shortreg);
    719         intregw = mkwildcard(intreg);
    720         fltregw = mkwildcard(fltreg);
    721 
    722         tmask[IREG] = (1<<EDI) | (1<<ESI) | (1<<EBX)
    723                     | (1<<EDX) | (1<<ECX) | (1<<EAX);
    724         vmask[IREG] = 0;
    725         tmask[FREG] = 0xff;
    726         vmask[FREG] = 0;
    727 
    728         cseg = 0;
    729         quo = mkreg("%%eax", EAX, 1, IREG);
    730         quo->x.regnode->mask |= 1<<EDX;
    731         rem = mkreg("%%edx", EDX, 1, IREG);
    732         rem->x.regnode->mask |= 1<<EAX;
    733 
    734         stabprefix = ".LL";
    735 }
    736 
    737 static Symbol rmap(int opk) {
    738         switch (optype(opk)) {
    739         case B: case P:
    740                 return intregw;
    741         case I: case U:
    742                 if (opsize(opk) == 1)
    743                         return charregw;
    744                 else if (opsize(opk) == 2)
    745                         return shortregw;
    746                 else
    747                         return intregw;
    748         case F:
    749                 return fltregw;
    750         default:
    751                 return 0;
    752         }
    753 }
    754 
    755 static Symbol prevg;
    756 
    757 static void globalend(void) {
    758         if (prevg && prevg->type->size > 0)
    759                 print(".size %s,%d\n", prevg->x.name, prevg->type->size);
    760         prevg = NULL;
    761 }
    762 
    763 static void progend(void) {
    764         globalend();
    765         (*IR->segment)(CODE);
    766         print(".ident \"LCC: 4.1\"\n");
    767 }
    768 
    769 static void target(Node p) {
    770         assert(p);
    771         switch (specific(p->op)) {
    772         case RSH+I: case RSH+U: case LSH+I: case LSH+U:
    773                 if (generic(p->kids[1]->op) != CNST
    774                 && !(   generic(p->kids[1]->op) == INDIR
    775                      && specific(p->kids[1]->kids[0]->op) == VREG+P
    776                      && p->kids[1]->syms[RX]->u.t.cse
    777                      && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST)) {
    778                         rtarget(p, 1, intreg[ECX]);
    779                         setreg(p, intreg[EAX]);
    780                 }
    781                 break;
    782         case MUL+U:
    783                 setreg(p, quo);
    784                 rtarget(p, 0, intreg[EAX]);
    785                 break;
    786         case DIV+I: case DIV+U:
    787                 setreg(p, quo);
    788                 rtarget(p, 0, intreg[EAX]);
    789                 rtarget(p, 1, intreg[ECX]);
    790                 break;
    791         case MOD+I: case MOD+U:
    792                 setreg(p, rem);
    793                 rtarget(p, 0, intreg[EAX]);
    794                 rtarget(p, 1, intreg[ECX]);
    795                 break;
    796         case ASGN+B:
    797                 rtarget(p, 0, intreg[EDI]);
    798                 rtarget(p->kids[1], 0, intreg[ESI]);
    799                 break;
    800         case ARG+B:
    801                 rtarget(p->kids[0], 0, intreg[ESI]);
    802                 break;
    803         case CVF+I:
    804                 setreg(p, intreg[EAX]);
    805                 break;
    806         case CALL+I: case CALL+U: case CALL+P: case CALL+V:
    807                 setreg(p, intreg[EAX]);
    808                 break;
    809         case RET+I: case RET+U: case RET+P:
    810                 rtarget(p, 0, intreg[EAX]);
    811                 break;
    812         }
    813 }
    814 
    815 static void clobber(Node p) {
    816         static int nstack = 0;
    817 
    818         assert(p);
    819         nstack = ckstack(p, nstack);
    820         switch (specific(p->op)) {
    821         case ASGN+B: case ARG+B:
    822                 spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p);
    823                 break;
    824         case EQ+F: case LE+F: case GE+F: case LT+F: case GT+F: case NE+F:
    825                 spill(1<<EAX, IREG, p);
    826                 break;
    827         case CALL+F:
    828                 spill(1<<EDX | 1<<EAX | 1<<ECX, IREG, p);
    829                 break;
    830         case CALL+I: case CALL+U: case CALL+P: case CALL+V:
    831                 spill(1<<EDX | 1<<ECX, IREG, p);
    832                 break;
    833         }
    834 }
    835 
    836 static void emit2(Node p) {
    837         int op = specific(p->op);
    838 #define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name)
    839 
    840         if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1)
    841                 print("movsbl %s,%s\n", preg(charreg), p->syms[RX]->x.name);
    842         else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1)
    843                 print("movsbl %s,%s\n", preg(charreg), p->syms[RX]->x.name);
    844         else if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2)
    845                 print("movswl %s,%s\n", preg(shortreg), p->syms[RX]->x.name);
    846         else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2)
    847                 print("movswl %s,%s\n", preg(shortreg), p->syms[RX]->x.name);
    848         else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1)
    849                 print("movzbl %s,%s\n", preg(charreg), p->syms[RX]->x.name);
    850         else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1)
    851                 print("movzbl %s,%s\n", preg(charreg), p->syms[RX]->x.name);
    852         else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2)
    853                 print("movzwl %s,%s\n", preg(shortreg), p->syms[RX]->x.name);
    854         else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2)
    855                 print("movzwl %s,%s\n", preg(shortreg), p->syms[RX]->x.name);
    856         else if (generic(op) == CVI || generic(op) == CVU || generic(op) == LOAD) {
    857                 char *dst = intreg[getregnum(p)]->x.name;
    858                 char *src = preg(intreg);
    859                 assert(opsize(p->op) <= opsize(p->x.kids[0]->op));
    860                 if (dst != src)
    861                         print("movl %s,%s\n", src, dst);
    862         }       
    863 }
    864 
    865 static void function(Symbol f, Symbol caller[], Symbol callee[], int n) {
    866         int i;
    867         
    868         globalend();
    869         print(".align 16\n");
    870         print(".type %s,@function\n", f->x.name);
    871         print("%s:\n", f->x.name);
    872         print("pushl %%ebp\n");
    873         if (pflag) {
    874                 static int plab;
    875                 print("movl %%esp,%%ebp\n");
    876                 (*IR->segment)(DATA);
    877                 print(".align 4\n.LP%d:\n.long 0\n", plab);
    878                 (*IR->segment)(CODE);
    879                 print("movl $.LP%d,%%edx\ncall mcount\n", plab);
    880                 plab++;
    881         }
    882         print("pushl %%ebx\n");
    883         print("pushl %%esi\n");
    884         print("pushl %%edi\n");
    885         print("movl %%esp,%%ebp\n");
    886 
    887         usedmask[0] = usedmask[1] = 0;
    888         freemask[0] = freemask[1] = ~0U;
    889         offset = 16 + 4;
    890         for (i = 0; callee[i]; i++) {
    891                 Symbol p = callee[i];
    892                 Symbol q = caller[i];
    893                 assert(q);
    894                 offset = roundup(offset, q->type->align);
    895                 p->x.offset = q->x.offset = offset;
    896                 p->x.name = q->x.name = stringf("%d", p->x.offset);
    897                 p->sclass = q->sclass = AUTO;
    898                 offset += roundup(q->type->size, 4);
    899         }
    900         assert(caller[i] == 0);
    901         offset = maxoffset = 0;
    902         gencode(caller, callee);
    903         framesize = roundup(maxoffset, 4);
    904         if (framesize > 0)
    905                 print("subl $%d,%%esp\n", framesize);
    906         emitcode();
    907         print("movl %%ebp,%%esp\n");
    908         print("popl %%edi\n");
    909         print("popl %%esi\n");
    910         print("popl %%ebx\n");
    911         print("popl %%ebp\n");
    912         print("ret\n");
    913         { int l = genlabel(1);
    914           print(".Lf%d:\n", l);
    915           print(".size %s,.Lf%d-%s\n", f->x.name, l, f->x.name);
    916         }
    917 }
    918 
    919 static void defsymbol(Symbol p) {
    920         if (p->scope >= LOCAL && p->sclass == STATIC)
    921                 p->x.name = stringf("%s.%d", p->name, genlabel(1));
    922         else if (p->generated)
    923                 p->x.name = stringf(".LC%s", p->name);
    924         else if (p->scope == GLOBAL || p->sclass == EXTERN)
    925                 p->x.name = stringf("%s", p->name);
    926         else
    927                 p->x.name = p->name;
    928 }
    929 
    930 static void segment(int n) {
    931         if (n == cseg)
    932                 return;
    933         cseg = n;
    934         if (cseg == CODE)
    935                 print(".text\n");
    936         else if (cseg == BSS)
    937                 print(".bss\n");
    938         else if (cseg == DATA || cseg == LIT)
    939                 print(".data\n");
    940 }
    941 
    942 static void defconst(int suffix, int size, Value v) {
    943         if (suffix == I && size == 1)
    944                 print(".byte %d\n",   v.u);
    945         else if (suffix == I && size == 2)
    946                 print(".word %d\n",   v.i);
    947         else if (suffix == I && size == 4)
    948                 print(".long %d\n",   v.i);
    949         else if (suffix == U && size == 1)
    950                 print(".byte %d\n", v.u);
    951         else if (suffix == U && size == 2)
    952                 print(".word %d\n", v.u);
    953         else if (suffix == U && size == 4)
    954                 print(".long %d\n", v.u);
    955         else if (suffix == P && size == 4)
    956                 print(".long %d\n", v.p);
    957         else if (suffix == F && size == 4) {
    958                 float f = v.d;
    959                 print(".long %d\n", *(unsigned *)&f);
    960         } else if (suffix == F && size == 8) {
    961                 double d = v.d;
    962                 unsigned *p = (unsigned *)&d;
    963                 print(".long %d\n.long %d\n", p[swap], p[!swap]);
    964         }
    965         else assert(0);
    966 }
    967 
    968 static void defaddress(Symbol p) {
    969         print(".long %s\n", p->x.name);
    970 }
    971 
    972 static void defstring(int n, char *str) {
    973         char *s;
    974 
    975         for (s = str; s < str + n; s++)
    976                 print(".byte %d\n", (*s)&0377);
    977 }
    978 
    979 static void export(Symbol p) {
    980         globalend();
    981         print(".globl %s\n", p->x.name);
    982 }
    983 
    984 static void import(Symbol p) {}
    985 
    986 static void global(Symbol p) {
    987         globalend();
    988         print(".align %d\n", p->type->align > 4 ? 4 : p->type->align);
    989         if (!p->generated) {
    990                 print(".type %s,@%s\n", p->x.name,
    991                         isfunc(p->type) ? "function" : "object");
    992                 if (p->type->size > 0)
    993                         print(".size %s,%d\n", p->x.name, p->type->size);
    994                 else
    995                         prevg = p;
    996         }
    997         if (p->u.seg == BSS) {
    998                 if (p->sclass == STATIC)
    999                         print(".lcomm %s,%d\n", p->x.name, p->type->size);
   1000                 else
   1001                         print(".comm %s,%d\n", p->x.name, p->type->size);
   1002         } else {
   1003                 print("%s:\n", p->x.name);
   1004         }
   1005 }
   1006 
   1007 static void space(int n) {
   1008         if (cseg != BSS)
   1009                 print(".space %d\n", n);
   1010 }
   1011 
   1012 Interface x86linuxIR = {
   1013         1, 1, 0,  /* char */
   1014         2, 2, 0,  /* short */
   1015         4, 4, 0,  /* int */
   1016         4, 4, 0,  /* long */
   1017         4, 4, 0,  /* long long */
   1018         4, 4, 1,  /* float */
   1019         8, 4, 1,  /* double */
   1020         8, 4, 1,  /* long double */
   1021         4, 4, 0,  /* T * */
   1022         0, 4, 0,  /* struct; so that ARGB keeps stack aligned */
   1023         1,        /* little_endian */
   1024         0,        /* mulops_calls */
   1025         0,        /* wants_callb */
   1026         1,        /* wants_argb */
   1027         0,        /* left_to_right */
   1028         0,        /* wants_dag */
   1029         0,        /* unsigned_char */
   1030         0, /* address */
   1031         blockbeg,
   1032         blockend,
   1033         defaddress,
   1034         defconst,
   1035         defstring,
   1036         defsymbol,
   1037         emit,
   1038         export,
   1039         function,
   1040         gen,
   1041         global,
   1042         import,
   1043         0, /* local */
   1044         progbeg,
   1045         progend,
   1046         segment,
   1047         space,
   1048         stabblock, stabend, 0, stabinit, stabline, stabsym, stabtype,
   1049         {1, rmap,
   1050             0, 0, 0,    /* blkfetch, blkstore, blkloop */
   1051             _label,
   1052             _rule,
   1053             _nts,
   1054             _kids,
   1055             _string,
   1056             _templates,
   1057             _isinstruction,
   1058             _ntname,
   1059             emit2,
   1060             0, /* doarg */
   1061             target,
   1062             clobber,
   1063         }
   1064 };
   1065 
   1066 void x86linux_init(int argc, char *argv[]) {
   1067         static int inited;
   1068         extern Interface x86IR;
   1069 
   1070         if (inited)
   1071                 return;
   1072         inited = 1;
   1073 #define xx(f) assert(!x86linuxIR.f); x86linuxIR.f = x86IR.f
   1074         xx(address);
   1075         xx(local);
   1076         xx(x.blkfetch);
   1077         xx(x.blkstore);
   1078         xx(x.blkloop);
   1079         xx(x.doarg);
   1080 #undef xx
   1081 }