Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

sparc.md (36632B)


      1 %{
      2 #include "c.h"
      3 #define NODEPTR_TYPE Node
      4 #define OP_LABEL(p) ((p)->op)
      5 #define LEFT_CHILD(p) ((p)->kids[0])
      6 #define RIGHT_CHILD(p) ((p)->kids[1])
      7 #define STATE_LABEL(p) ((p)->x.state)
      8 static void address(Symbol, Symbol, long);
      9 static void blkfetch(int, int, int, int);
     10 static void blkloop(int, int, int, int, int, int[]);
     11 static void blkstore(int, int, int, int);
     12 static void defaddress(Symbol);
     13 static void defconst(int, int, Value);
     14 static void defstring(int, char *);
     15 static void defsymbol(Symbol);
     16 static void doarg(Node);
     17 static void emit2(Node);
     18 static void export(Symbol);
     19 static void clobber(Node);
     20 static void function(Symbol, Symbol [], Symbol [], int);
     21 static void global(Symbol);
     22 static void import(Symbol);
     23 static void local(Symbol);
     24 static void progbeg(int, char **);
     25 static void progend(void);
     26 static void segment(int);
     27 static void space(int);
     28 static void target(Node);
     29 static int imm(Node);
     30 static void renameregs(void);
     31 extern Interface sparcIR, solarisIR;
     32 static void defsymbol2(Symbol);
     33 static void export2(Symbol);
     34 static void globalend(void);
     35 static void global2(Symbol);
     36 static void segment2(int);
     37 static void progend2(void);
     38 
     39 extern char *stabprefix;
     40 extern void stabblock(int, int, Symbol*);
     41 extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *);
     42 extern void stabfend(Symbol, int);
     43 extern void stabinit(char *, int, char *[]);
     44 extern void stabline(Coordinate *);
     45 extern void stabsym(Symbol);
     46 extern void stabtype(Symbol);
     47 static Symbol greg[32], gregw;
     48 static Symbol *oreg = &greg[8], *ireg = &greg[24];
     49 static Symbol freg[32], freg2[32];
     50 static Symbol fregw, freg2w;
     51 
     52 static int regvars;
     53 static int retstruct;
     54 
     55 static int pflag = 0;
     56 
     57 static int cseg;
     58 
     59 %}
     60 %start stmt
     61 %term CNSTF4=4113
     62 %term CNSTF8=8209
     63 %term CNSTF16=16401
     64 %term CNSTI1=1045
     65 %term CNSTI2=2069
     66 %term CNSTI4=4117
     67 %term CNSTI8=8213
     68 %term CNSTP4=4119
     69 %term CNSTP8=8215
     70 %term CNSTU1=1046
     71 %term CNSTU2=2070
     72 %term CNSTU4=4118
     73 %term CNSTU8=8214
     74  
     75 %term ARGB=41
     76 %term ARGF4=4129
     77 %term ARGF8=8225
     78 %term ARGF16=16417
     79 %term ARGI4=4133
     80 %term ARGI8=8229
     81 %term ARGP4=4135
     82 %term ARGP8=8231
     83 %term ARGU4=4134
     84 %term ARGU8=8230
     85 
     86 %term ASGNB=57
     87 %term ASGNF4=4145
     88 %term ASGNF8=8241
     89 %term ASGNF16=16433
     90 %term ASGNI1=1077
     91 %term ASGNI2=2101
     92 %term ASGNI4=4149
     93 %term ASGNI8=8245
     94 %term ASGNP4=4151
     95 %term ASGNP8=8247
     96 %term ASGNU1=1078
     97 %term ASGNU2=2102
     98 %term ASGNU4=4150
     99 %term ASGNU8=8246
    100 
    101 %term INDIRB=73
    102 %term INDIRF4=4161
    103 %term INDIRF8=8257
    104 %term INDIRF16=16449
    105 %term INDIRI1=1093
    106 %term INDIRI2=2117
    107 %term INDIRI4=4165
    108 %term INDIRI8=8261
    109 %term INDIRP4=4167
    110 %term INDIRP8=8263
    111 %term INDIRU1=1094
    112 %term INDIRU2=2118
    113 %term INDIRU4=4166
    114 %term INDIRU8=8262
    115 
    116 %term CVFF4=4209
    117 %term CVFF8=8305
    118 %term CVFF16=16497
    119 %term CVFI4=4213
    120 %term CVFI8=8309
    121 
    122 %term CVIF4=4225
    123 %term CVIF8=8321
    124 %term CVIF16=16513
    125 %term CVII1=1157
    126 %term CVII2=2181
    127 %term CVII4=4229
    128 %term CVII8=8325
    129 %term CVIU1=1158
    130 %term CVIU2=2182
    131 %term CVIU4=4230
    132 %term CVIU8=8326
    133 
    134 %term CVPP4=4247
    135 %term CVPP8=8343
    136 %term CVPP16=16535
    137 %term CVPU4=4246
    138 %term CVPU8=8342
    139 
    140 %term CVUI1=1205
    141 %term CVUI2=2229
    142 %term CVUI4=4277
    143 %term CVUI8=8373
    144 %term CVUP4=4279
    145 %term CVUP8=8375
    146 %term CVUP16=16567
    147 %term CVUU1=1206
    148 %term CVUU2=2230
    149 %term CVUU4=4278
    150 %term CVUU8=8374
    151 
    152 %term NEGF4=4289
    153 %term NEGF8=8385
    154 %term NEGF16=16577
    155 %term NEGI4=4293
    156 %term NEGI8=8389
    157 
    158 %term CALLB=217
    159 %term CALLF4=4305
    160 %term CALLF8=8401
    161 %term CALLF16=16593
    162 %term CALLI4=4309
    163 %term CALLI8=8405
    164 %term CALLP4=4311
    165 %term CALLP8=8407
    166 %term CALLU4=4310
    167 %term CALLU8=8406
    168 %term CALLV=216
    169 
    170 %term RETF4=4337
    171 %term RETF8=8433
    172 %term RETF16=16625
    173 %term RETI4=4341
    174 %term RETI8=8437
    175 %term RETP4=4343
    176 %term RETP8=8439
    177 %term RETU4=4342
    178 %term RETU8=8438
    179 %term RETV=248
    180 
    181 %term ADDRGP4=4359
    182 %term ADDRGP8=8455
    183 
    184 %term ADDRFP4=4375
    185 %term ADDRFP8=8471
    186 
    187 %term ADDRLP4=4391
    188 %term ADDRLP8=8487
    189 
    190 %term ADDF4=4401
    191 %term ADDF8=8497
    192 %term ADDF16=16689
    193 %term ADDI4=4405
    194 %term ADDI8=8501
    195 %term ADDP4=4407
    196 %term ADDP8=8503
    197 %term ADDU4=4406
    198 %term ADDU8=8502
    199 
    200 %term SUBF4=4417
    201 %term SUBF8=8513
    202 %term SUBF16=16705
    203 %term SUBI4=4421
    204 %term SUBI8=8517
    205 %term SUBP4=4423
    206 %term SUBP8=8519
    207 %term SUBU4=4422
    208 %term SUBU8=8518
    209 
    210 %term LSHI4=4437
    211 %term LSHI8=8533
    212 %term LSHU4=4438
    213 %term LSHU8=8534
    214 
    215 %term MODI4=4453
    216 %term MODI8=8549
    217 %term MODU4=4454
    218 %term MODU8=8550
    219 
    220 %term RSHI4=4469
    221 %term RSHI8=8565
    222 %term RSHU4=4470
    223 %term RSHU8=8566
    224 
    225 %term BANDI4=4485
    226 %term BANDI8=8581
    227 %term BANDU4=4486
    228 %term BANDU8=8582
    229 
    230 %term BCOMI4=4501
    231 %term BCOMI8=8597
    232 %term BCOMU4=4502
    233 %term BCOMU8=8598
    234 
    235 %term BORI4=4517
    236 %term BORI8=8613
    237 %term BORU4=4518
    238 %term BORU8=8614
    239 
    240 %term BXORI4=4533
    241 %term BXORI8=8629
    242 %term BXORU4=4534
    243 %term BXORU8=8630
    244 
    245 %term DIVF4=4545
    246 %term DIVF8=8641
    247 %term DIVF16=16833
    248 %term DIVI4=4549
    249 %term DIVI8=8645
    250 %term DIVU4=4550
    251 %term DIVU8=8646
    252 
    253 %term MULF4=4561
    254 %term MULF8=8657
    255 %term MULF16=16849
    256 %term MULI4=4565
    257 %term MULI8=8661
    258 %term MULU4=4566
    259 %term MULU8=8662
    260 
    261 %term EQF4=4577
    262 %term EQF8=8673
    263 %term EQF16=16865
    264 %term EQI4=4581
    265 %term EQI8=8677
    266 %term EQU4=4582
    267 %term EQU8=8678
    268 
    269 %term GEF4=4593
    270 %term GEF8=8689
    271 %term GEI4=4597
    272 %term GEI8=8693
    273 %term GEI16=16885
    274 %term GEU4=4598
    275 %term GEU8=8694
    276 
    277 %term GTF4=4609
    278 %term GTF8=8705
    279 %term GTF16=16897
    280 %term GTI4=4613
    281 %term GTI8=8709
    282 %term GTU4=4614
    283 %term GTU8=8710
    284 
    285 %term LEF4=4625
    286 %term LEF8=8721
    287 %term LEF16=16913
    288 %term LEI4=4629
    289 %term LEI8=8725
    290 %term LEU4=4630
    291 %term LEU8=8726
    292 
    293 %term LTF4=4641
    294 %term LTF8=8737
    295 %term LTF16=16929
    296 %term LTI4=4645
    297 %term LTI8=8741
    298 %term LTU4=4646
    299 %term LTU8=8742
    300 
    301 %term NEF4=4657
    302 %term NEF8=8753
    303 %term NEF16=16945
    304 %term NEI4=4661
    305 %term NEI8=8757
    306 %term NEU4=4662
    307 %term NEU8=8758
    308 
    309 %term JUMPV=584
    310 
    311 %term LABELV=600
    312 
    313 %term LOADB=233
    314 %term LOADF4=4321
    315 %term LOADF8=8417
    316 %term LOADF16=16609
    317 %term LOADI1=1253
    318 %term LOADI2=2277
    319 %term LOADI4=4325
    320 %term LOADI8=8421
    321 %term LOADP4=4327
    322 %term LOADP8=8423
    323 %term LOADU1=1254
    324 %term LOADU2=2278
    325 %term LOADU4=4326
    326 %term LOADU8=8422
    327 
    328 %term VREGP=711
    329 %%
    330 reg:  INDIRI1(VREGP)     "# read register\n"
    331 reg:  INDIRU1(VREGP)     "# read register\n"
    332 
    333 reg:  INDIRI2(VREGP)     "# read register\n"
    334 reg:  INDIRU2(VREGP)     "# read register\n"
    335 
    336 reg:  INDIRF4(VREGP)     "# read register\n"
    337 reg:  INDIRI4(VREGP)     "# read register\n"
    338 reg:  INDIRP4(VREGP)     "# read register\n"
    339 reg:  INDIRU4(VREGP)     "# read register\n"
    340 
    341 reg:  INDIRF8(VREGP)     "# read register\n"
    342 reg:  INDIRI8(VREGP)     "# read register\n"
    343 reg:  INDIRP8(VREGP)     "# read register\n"
    344 reg:  INDIRU8(VREGP)     "# read register\n"
    345 
    346 stmt: ASGNI1(VREGP,reg)  "# write register\n"
    347 stmt: ASGNU1(VREGP,reg)  "# write register\n"
    348 
    349 stmt: ASGNI2(VREGP,reg)  "# write register\n"
    350 stmt: ASGNU2(VREGP,reg)  "# write register\n"
    351 
    352 stmt: ASGNF4(VREGP,reg)  "# write register\n"
    353 stmt: ASGNI4(VREGP,reg)  "# write register\n"
    354 stmt: ASGNP4(VREGP,reg)  "# write register\n"
    355 stmt: ASGNU4(VREGP,reg)  "# write register\n"
    356 
    357 stmt: ASGNF8(VREGP,reg)  "# write register\n"
    358 stmt: ASGNI8(VREGP,reg)  "# write register\n"
    359 stmt: ASGNP8(VREGP,reg)  "# write register\n"
    360 stmt: ASGNU8(VREGP,reg)  "# write register\n"
    361 con: CNSTI1  "%a"
    362 con: CNSTU1  "%a"
    363 
    364 con: CNSTI2  "%a"
    365 con: CNSTU2  "%a"
    366 
    367 con: CNSTI4  "%a"
    368 con: CNSTU4  "%a"
    369 con: CNSTP4  "%a"
    370 
    371 con: CNSTI8  "%a"
    372 con: CNSTU8  "%a"
    373 con: CNSTP8  "%a"
    374 stmt: reg  ""
    375 reg: ADDRGP4  "set %a,%%%c\n"  1
    376 stk13: ADDRFP4  "%a"                  imm(a)
    377 stk13: ADDRLP4  "%a"                  imm(a)
    378 reg:   stk13   "add %0,%%fp,%%%c\n"  1
    379 stk: ADDRFP4  "set %a,%%%c\n"                      2
    380 stk: ADDRLP4  "set %a,%%%c\n"                      2
    381 reg: ADDRFP4  "set %a,%%%c\nadd %%%c,%%fp,%%%c\n"  3
    382 reg: ADDRLP4  "set %a,%%%c\nadd %%%c,%%fp,%%%c\n"  3
    383 con13: CNSTI1  "%a"  imm(a)
    384 con13: CNSTI2  "%a"  imm(a)
    385 con13: CNSTI4  "%a"  imm(a)
    386 con13: CNSTU1  "%a"  imm(a)
    387 con13: CNSTU2  "%a"  imm(a)
    388 con13: CNSTU4  "%a"  imm(a)
    389 con13: CNSTP4  "%a"  imm(a)
    390 base: ADDI4(reg,con13)  "%%%0+%1"
    391 base: ADDP4(reg,con13)  "%%%0+%1"
    392 base: ADDU4(reg,con13)  "%%%0+%1"
    393 base: reg    "%%%0"
    394 base: con13  "%0"
    395 base: stk13  "%%fp+%0"
    396 addr: base           "%0"
    397 addr: ADDI4(reg,reg)  "%%%0+%%%1"
    398 addr: ADDP4(reg,reg)  "%%%0+%%%1"
    399 addr: ADDU4(reg,reg)  "%%%0+%%%1"
    400 addr: stk            "%%fp+%%%0"
    401 reg:  INDIRI1(addr)     "ldsb [%0],%%%c\n"  1
    402 reg:  INDIRI2(addr)     "ldsh [%0],%%%c\n"  1
    403 reg:  INDIRI4(addr)     "ld [%0],%%%c\n"    1
    404 reg:  INDIRU1(addr)     "ldub [%0],%%%c\n"  1
    405 reg:  INDIRU2(addr)     "lduh [%0],%%%c\n"  1
    406 reg:  INDIRU4(addr)     "ld [%0],%%%c\n"    1
    407 reg:  INDIRP4(addr)     "ld [%0],%%%c\n"    1
    408 reg:  INDIRF4(addr)     "ld [%0],%%f%c\n"   1
    409 stmt: ASGNI1(addr,reg)  "stb %%%1,[%0]\n"   1
    410 stmt: ASGNI2(addr,reg)  "sth %%%1,[%0]\n"   1
    411 stmt: ASGNI4(addr,reg)  "st %%%1,[%0]\n"    1
    412 stmt: ASGNU1(addr,reg)  "stb %%%1,[%0]\n"   1
    413 stmt: ASGNU2(addr,reg)  "sth %%%1,[%0]\n"   1
    414 stmt: ASGNU4(addr,reg)  "st %%%1,[%0]\n"    1
    415 stmt: ASGNP4(addr,reg)  "st %%%1,[%0]\n"    1
    416 stmt: ASGNF4(addr,reg)  "st %%f%1,[%0]\n"   1
    417 addrl: ADDRLP4            "%%%fp+%a"          imm(a)
    418 
    419 reg:   INDIRF8(addrl)     "ldd [%0],%%f%c\n"  1
    420 stmt:  ASGNF8(addrl,reg)  "std %%f%1,[%0]\n"  1
    421 reg:  INDIRF8(base)     "ld2 [%0],%%f%c\n"  2
    422 stmt: ASGNF8(base,reg)  "st2 %%f%1,[%0]\n"  2
    423 spill:  ADDRLP4          "%a" !imm(a)
    424 
    425 stmt: ASGNI1(spill,reg)  "set %0,%%g1\nstb %%%1,[%%fp+%%g1]\n"
    426 stmt: ASGNI2(spill,reg)  "set %0,%%g1\nsth %%%1,[%%fp+%%g1]\n"
    427 stmt: ASGNI4(spill,reg)  "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n"
    428 stmt: ASGNU1(spill,reg)  "set %0,%%g1\nstb %%%1,[%%fp+%%g1]\n"
    429 stmt: ASGNU2(spill,reg)  "set %0,%%g1\nsth %%%1,[%%fp+%%g1]\n"
    430 stmt: ASGNU4(spill,reg)  "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n"
    431 stmt: ASGNP4(spill,reg)  "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n"
    432 stmt: ASGNF4(spill,reg)  "set %0,%%g1\nst %%f%1,[%%fp+%%g1]\n"
    433 stmt: ASGNF8(spill,reg)  "set %0,%%g1\nstd %%f%1,[%%fp+%%g1]\n"
    434 reg: CVII4(INDIRI1(addr))  "ldsb [%0],%%%c\n"  1
    435 reg: CVII4(INDIRI2(addr))  "ldsh [%0],%%%c\n"  1
    436 reg: CVUU4(INDIRU1(addr))  "ldub [%0],%%%c\n"  1
    437 reg: CVUU4(INDIRU2(addr))  "lduh [%0],%%%c\n"  1
    438 reg: CVUI4(INDIRU1(addr))  "ldub [%0],%%%c\n"  1
    439 reg: CVUI4(INDIRU2(addr))  "lduh [%0],%%%c\n"  1
    440 reg: LOADI1(reg)  "mov %%%0,%%%c\n"  move(a)
    441 reg: LOADI2(reg)  "mov %%%0,%%%c\n"  move(a)
    442 reg: LOADI4(reg)  "mov %%%0,%%%c\n"  move(a)
    443 reg: LOADP4(reg)  "mov %%%0,%%%c\n"  move(a)
    444 reg: LOADU1(reg)  "mov %%%0,%%%c\n"  move(a)
    445 reg: LOADU2(reg)  "mov %%%0,%%%c\n"  move(a)
    446 reg: LOADU4(reg)  "mov %%%0,%%%c\n"  move(a)
    447 reg: CNSTI1  "# reg\n"  range(a, 0, 0)
    448 reg: CNSTI2  "# reg\n"  range(a, 0, 0)
    449 reg: CNSTI4  "# reg\n"  range(a, 0, 0)
    450 reg: CNSTP4  "# reg\n"  range(a, 0, 0)
    451 reg: CNSTU1  "# reg\n"  range(a, 0, 0)
    452 reg: CNSTU2  "# reg\n"  range(a, 0, 0)
    453 reg: CNSTU4  "# reg\n"  range(a, 0, 0)
    454 reg: con  "set %0,%%%c\n"  1
    455 rc: con13  "%0"
    456 rc: reg    "%%%0"
    457 reg: ADDI4(reg,rc)   "add %%%0,%1,%%%c\n"  1
    458 reg: ADDP4(reg,rc)   "add %%%0,%1,%%%c\n"  1
    459 reg: ADDU4(reg,rc)   "add %%%0,%1,%%%c\n"  1
    460 reg: BANDI4(reg,rc)  "and %%%0,%1,%%%c\n"  1
    461 reg: BORI4(reg,rc)   "or %%%0,%1,%%%c\n"   1
    462 reg: BXORI4(reg,rc)  "xor %%%0,%1,%%%c\n"  1
    463 reg: BANDU4(reg,rc)  "and %%%0,%1,%%%c\n"  1
    464 reg: BORU4(reg,rc)   "or %%%0,%1,%%%c\n"   1
    465 reg: BXORU4(reg,rc)  "xor %%%0,%1,%%%c\n"  1
    466 reg: SUBI4(reg,rc)   "sub %%%0,%1,%%%c\n"  1
    467 reg: SUBP4(reg,rc)   "sub %%%0,%1,%%%c\n"  1
    468 reg: SUBU4(reg,rc)   "sub %%%0,%1,%%%c\n"  1
    469 rc5: CNSTI4  "%a"    range(a, 0, 31)
    470 rc5: reg    "%%%0"
    471 reg: LSHI4(reg,rc5)  "sll %%%0,%1,%%%c\n"  1
    472 reg: LSHU4(reg,rc5)  "sll %%%0,%1,%%%c\n"  1
    473 reg: RSHI4(reg,rc5)  "sra %%%0,%1,%%%c\n"  1
    474 reg: RSHU4(reg,rc5)  "srl %%%0,%1,%%%c\n"  1
    475 reg: BANDI4(reg,BCOMI4(rc))  "andn %%%0,%1,%%%c\n"  1
    476 reg: BORI4(reg,BCOMI4(rc))   "orn %%%0,%1,%%%c\n"   1
    477 reg: BXORI4(reg,BCOMI4(rc))  "xnor %%%0,%1,%%%c\n"  1
    478 reg: BANDU4(reg,BCOMU4(rc))  "andn %%%0,%1,%%%c\n"  1
    479 reg: BORU4(reg,BCOMU4(rc))   "orn %%%0,%1,%%%c\n"   1
    480 reg: BXORU4(reg,BCOMU4(rc))  "xnor %%%0,%1,%%%c\n"  1
    481 reg: NEGI4(reg)   "neg %%%0,%%%c\n"  1
    482 reg: BCOMI4(reg)  "not %%%0,%%%c\n"  1
    483 reg: BCOMU4(reg)  "not %%%0,%%%c\n"  1
    484 reg: CVII4(reg)  "sll %%%0,8*(4-%a),%%%c; sra %%%c,8*(4-%a),%%%c\n"  2
    485 reg: CVUU4(reg)  "sll %%%0,8*(4-%a),%%%c; srl %%%c,8*(4-%a),%%%c\n"  2
    486 reg: CVUU4(reg)  "and %%%0,0xff,%%%c\n" (a->syms[0]->u.c.v.i == 1 ? 1 : LBURG_MAX)
    487 reg: CVUU4(reg)  "set 0xffff,%%g1; and %%%0,%%g1,%%%c\n"  2
    488 reg: CVUI4(reg)  "and %%%0,0xff,%%%c\n" (a->syms[0]->u.c.v.i == 1 ? 1 : LBURG_MAX)
    489 reg: CVUI4(reg)  "set 0xffff,%%g1; and %%%0,%%g1,%%%c\n"  2
    490 addrg: ADDRGP4        "%a"
    491 stmt:  JUMPV(addrg)  "ba %0; nop\n"   2
    492 stmt:  JUMPV(addr)   "jmp %0; nop\n"  2
    493 stmt:  LABELV        "%a:\n"
    494 stmt: EQI4(reg,rc)  "cmp %%%0,%1; be %a; nop\n"    3
    495 stmt: EQU4(reg,rc)  "cmp %%%0,%1; be %a; nop\n"    3
    496 stmt: GEI4(reg,rc)  "cmp %%%0,%1; bge %a; nop\n"   3
    497 stmt: GEU4(reg,rc)  "cmp %%%0,%1; bgeu %a; nop\n"  3
    498 stmt: GTI4(reg,rc)  "cmp %%%0,%1; bg %a; nop\n"    3
    499 stmt: GTU4(reg,rc)  "cmp %%%0,%1; bgu %a; nop\n"   3
    500 stmt: LEI4(reg,rc)  "cmp %%%0,%1; ble %a; nop\n"   3
    501 stmt: LEU4(reg,rc)  "cmp %%%0,%1; bleu %a; nop\n"  3
    502 stmt: LTI4(reg,rc)  "cmp %%%0,%1; bl %a; nop\n"    3
    503 stmt: LTU4(reg,rc)  "cmp %%%0,%1; blu %a; nop\n"   3
    504 stmt: NEI4(reg,rc)  "cmp %%%0,%1; bne %a; nop\n"   3
    505 stmt: NEU4(reg,rc)  "cmp %%%0,%1; bne %a; nop\n"   3
    506 call: ADDRGP4           "%a"
    507 call: addr             "%0"
    508 reg:  CALLF8(call)      "call %0; nop\n"                2
    509 reg:  CALLF4(call)      "call %0; nop\n"                2
    510 reg:  CALLI4(call)      "call %0; nop\n"                2
    511 reg:  CALLP4(call)      "call %0; nop\n"                2
    512 reg:  CALLU4(call)      "call %0; nop\n"                2
    513 stmt: CALLV(call)       "call %0; nop\n"                2
    514 stmt: CALLB(call,reg)   "call %0; st %%%1,[%%sp+64]; unimp %b&0xfff\n"  3
    515 
    516 stmt: RETF8(reg)  "# ret\n"  1
    517 stmt: RETF4(reg)  "# ret\n"  1
    518 stmt: RETI4(reg)  "# ret\n"  1
    519 stmt: RETU4(reg)  "# ret\n"  1
    520 stmt: RETP4(reg)  "# ret\n"  1
    521 stmt: ARGI4(reg)  "st %%%0,[%%sp+4*%c+68]\n"  1
    522 stmt: ARGU4(reg)  "st %%%0,[%%sp+4*%c+68]\n"  1
    523 stmt: ARGP4(reg)  "st %%%0,[%%sp+4*%c+68]\n"  1
    524 stmt: ARGF4(reg)  "# ARGF4\n"  1
    525 stmt: ARGF8(reg)  "# ARGF8\n"  1
    526 
    527 reg: DIVI4(reg,rc)   "sra %%%0,31,%%g1; wr %%g0,%%g1,%%y; nop; nop; nop; sdiv %%%0,%1,%%%c\n"       6
    528 
    529 reg: DIVU4(reg,rc)   "wr %%g0,%%g0,%%y; nop; nop; nop; udiv %%%0,%1,%%%c\n"       5
    530 
    531 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
    532 
    533 
    534 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
    535 
    536 
    537 reg: MULI4(rc,reg)   "smul %%%1,%0,%%%c\n"  1
    538 reg: MULU4(rc,reg)   "umul %%%1,%0,%%%c\n"  1
    539 reg: ADDF8(reg,reg)  "faddd %%f%0,%%f%1,%%f%c\n"  1
    540 reg: ADDF4(reg,reg)  "fadds %%f%0,%%f%1,%%f%c\n"  1
    541 reg: DIVF8(reg,reg)  "fdivd %%f%0,%%f%1,%%f%c\n"  1
    542 reg: DIVF4(reg,reg)  "fdivs %%f%0,%%f%1,%%f%c\n"  1
    543 reg: MULF8(reg,reg)  "fmuld %%f%0,%%f%1,%%f%c\n"  1
    544 reg: MULF4(reg,reg)  "fmuls %%f%0,%%f%1,%%f%c\n"  1
    545 reg: SUBF8(reg,reg)  "fsubd %%f%0,%%f%1,%%f%c\n"  1
    546 reg: SUBF4(reg,reg)  "fsubs %%f%0,%%f%1,%%f%c\n"  1
    547 reg: NEGF4(reg)   "fnegs %%f%0,%%f%c\n"  1
    548 reg: LOADF4(reg)  "fmovs %%f%0,%%f%c\n"  1
    549 reg: CVFF4(reg)   "fdtos %%f%0,%%f%c\n"  1
    550 reg: CVFF8(reg)   "fstod %%f%0,%%f%c\n"  1
    551 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)
    552 
    553 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)
    554 
    555 reg: CVIF4(reg)  "st %%%0,[%%sp+64]; ld [%%sp+64],%%f%c; fitos %%f%c,%%f%c\n"  3
    556 
    557 reg: CVIF8(reg)  "st %%%0,[%%sp+64]; ld [%%sp+64],%%f%c; fitod %%f%c,%%f%c\n"  3
    558 
    559 rel: EQF8(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbue"
    560 rel: EQF4(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbue"
    561 rel: GEF8(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbuge"
    562 rel: GEF4(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbuge"
    563 rel: GTF8(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbug"
    564 rel: GTF4(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbug"
    565 rel: LEF8(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbule"
    566 rel: LEF4(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbule"
    567 rel: LTF8(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbul"
    568 rel: LTF4(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbul"
    569 rel: NEF8(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbne"
    570 rel: NEF4(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbne"
    571 
    572 stmt: rel  "%0 %a; nop\n"  4
    573 reg:  LOADF8(reg)  "# LOADD\n"  2
    574 
    575 reg:  NEGF8(reg)  "# NEGD\n"  2
    576 
    577 stmt:  ASGNB(reg,INDIRB(reg))  "# ASGNB\n"
    578 
    579 %%
    580 static void progend(void){}
    581 static void progbeg(int argc, char *argv[]) {
    582         int i;
    583 
    584         {
    585                 union {
    586                         char c;
    587                         int i;
    588                 } u;
    589                 u.i = 0;
    590                 u.c = 1;
    591                 swap = ((int)(u.i == 1)) != IR->little_endian;
    592         }
    593         parseflags(argc, argv);
    594         for (i = 0; i < argc; i++)
    595                 if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-pg") == 0)
    596                         pflag = 1;
    597         if (IR == &solarisIR)
    598                 stabprefix = ".LL";
    599         else
    600                 stabprefix = "L";
    601         for (i = 0; i < 8; i++) {
    602                 greg[i +  0] = mkreg(stringf("g%d", i), i +  0, 1, IREG);
    603                 greg[i +  8] = mkreg(stringf("o%d", i), i +  8, 1, IREG);
    604                 greg[i + 16] = mkreg(stringf("l%d", i), i + 16, 1, IREG);
    605                 greg[i + 24] = mkreg(stringf("i%d", i), i + 24, 1, IREG);
    606         }
    607         gregw = mkwildcard(greg);
    608         for (i = 0; i < 32; i++)
    609                 freg[i]  = mkreg("%d", i, 1, FREG);
    610         for (i = 0; i < 31; i += 2)
    611                 freg2[i] = mkreg("%d", i, 3, FREG);
    612         fregw = mkwildcard(freg);
    613         freg2w = mkwildcard(freg2);
    614         tmask[IREG] = 0x3fff3e00;
    615         vmask[IREG] = 0x3ff00000;
    616         tmask[FREG]  = ~(unsigned)0;
    617         vmask[FREG]  = 0;
    618 }
    619 static Symbol rmap(int opk) {
    620         switch (optype(opk)) {
    621         case I: case U: case P: case B:
    622                 return gregw;
    623         case F:
    624                 return opsize(opk) == 4 ? fregw : freg2w;
    625         default:
    626                 return 0;
    627         }
    628 }
    629 static void target(Node p) {
    630         assert(p);
    631         switch (specific(p->op)) {
    632         case CNST+I: case CNST+U: case CNST+P:
    633                 if (range(p, 0, 0) == 0) {
    634                         setreg(p, greg[0]);
    635                         p->x.registered = 1;
    636                 }
    637                 break;
    638         case CALL+B:
    639                 assert(p->syms[1] && p->syms[1]->type && isfunc(p->syms[1]->type));
    640                 p->syms[1] = intconst(freturn(p->syms[1]->type)->size);
    641                 break;
    642         case CALL+F: setreg(p, opsize(p->op)==4?freg[0]:freg2[0]);     break;
    643         case CALL+I: case CALL+P: case CALL+U:
    644         case CALL+V: setreg(p, oreg[0]);      break;
    645         case RET+F:  rtarget(p, 0, opsize(p->op)==4?freg[0]:freg2[0]);  break;
    646         case RET+I: case RET+P: case RET+U:
    647                 rtarget(p, 0, ireg[0]);
    648                 p->kids[0]->x.registered = 1;
    649                 break;
    650         case ARG+I: case ARG+P: case ARG+U:
    651                 if (p->syms[RX]->u.c.v.i < 6) {
    652                         rtarget(p, 0, oreg[p->syms[RX]->u.c.v.i]);
    653                         p->op = LOAD+opkind(p->op);
    654                         setreg(p, oreg[p->syms[RX]->u.c.v.i]);
    655                 }
    656                 break;
    657         }
    658 }
    659 static void clobber(Node p) {
    660         assert(p);
    661         switch (specific(p->op)) {
    662         case CALL+B: case CALL+F: case CALL+I:
    663                 spill(~(unsigned)3, FREG, p);
    664                 break;
    665         case CALL+V:
    666                 spill(oreg[0]->x.regnode->mask, IREG, p);
    667                 spill(~(unsigned)3, FREG, p);
    668                 break;
    669         case ARG+F:
    670                 if (opsize(p->op) == 4 && p->syms[2]->u.c.v.i <= 6)
    671                         spill((1<<(p->syms[2]->u.c.v.i + 8)), IREG, p);
    672                 else if (opsize(p->op) == 8 && p->syms[2]->u.c.v.i <= 5)
    673                         spill((3<<(p->syms[2]->u.c.v.i + 8))&0xff00, IREG, p);
    674                 break;
    675         }
    676 }
    677 static int imm(Node p) {
    678         return range(p, -4096, 4091);
    679 }
    680 static void doarg(Node p) {
    681         assert(p && p->syms[0] && p->op != ARG+B);
    682         p->syms[RX] = intconst(mkactual(4,
    683                 p->syms[0]->u.c.v.i)/4);
    684 }
    685 static void emit2(Node p) {
    686         switch (p->op) {
    687         case ARG+F+sizeop(4): {
    688                 int n = p->syms[RX]->u.c.v.i;
    689                 print("st %%f%d,[%%sp+4*%d+68]\n",
    690                         getregnum(p->x.kids[0]), n);
    691                 if (n <= 5)
    692                         print("ld [%%sp+4*%d+68],%%o%d\n", n, n);
    693                 break;
    694         }
    695         case ARG+F+sizeop(8): {
    696                 int n = p->syms[RX]->u.c.v.i;
    697                 int src = getregnum(p->x.kids[0]);
    698                 print("st %%f%d,[%%sp+4*%d+68]\n", src, n);
    699                 print("st %%f%d,[%%sp+4*%d+68]\n", src+1, n+1);
    700                 if (n <= 5)
    701                         print("ld [%%sp+4*%d+68],%%o%d\n", n, n);
    702                 if (n <= 4)
    703                         print("ld [%%sp+4*%d+68],%%o%d\n", n+1, n+1);
    704                 break;
    705         }
    706         case LOAD+F+sizeop(8): {
    707                 int dst = getregnum(p);
    708                 int src = getregnum(p->x.kids[0]);
    709                 print("fmovs %%f%d,%%f%d; ", src,   dst);
    710                 print("fmovs %%f%d,%%f%d\n", src+1, dst+1);
    711                 break;
    712         }
    713         case NEG+F+sizeop(8): {
    714                 int dst = getregnum(p);
    715                 int src = getregnum(p->x.kids[0]);
    716                 print("fnegs %%f%d,%%f%d; ", src,   dst);
    717                 print("fmovs %%f%d,%%f%d\n", src+1, dst+1);
    718                 break;
    719         }
    720         case ASGN+B: {
    721                 static int tmpregs[] = { 1, 2, 3 };
    722                 dalign = salign = p->syms[1]->u.c.v.i;
    723                 blkcopy(getregnum(p->x.kids[0]), 0,
    724                         getregnum(p->x.kids[1]), 0,
    725                         p->syms[0]->u.c.v.i, tmpregs);
    726                 break;
    727         }
    728         }
    729 }
    730 static void local(Symbol p) {
    731         if (retstruct) {
    732                 assert(p == retv);
    733                 p->x.name = stringd(4*16);
    734                 p->x.offset = 4*16;
    735                 p->sclass = AUTO;
    736                 retstruct = 0;
    737                 return;
    738         }
    739         if (isscalar(p->type) && !p->addressed && !isfloat(p->type))
    740                 p->sclass = REGISTER;
    741         if (askregvar(p, rmap(ttob(p->type))) == 0)
    742                 mkauto(p);
    743         else if (p->scope > LOCAL)
    744                 regvars++;
    745 }
    746 static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
    747         int autos = 0, i, leaf, reg, varargs;
    748 
    749         if (IR == &solarisIR)
    750                 globalend();
    751         regvars = 0;
    752         for (i = 0; callee[i]; i++)
    753                 ;
    754         varargs = variadic(f->type)
    755                 || i > 0 && strcmp(callee[i-1]->name,
    756                         "__builtin_va_alist") == 0;
    757         usedmask[0] = usedmask[1] = 0;
    758         freemask[0] = freemask[1] = ~(unsigned)0;
    759         for (i = 0; i < 8; i++)
    760                 ireg[i]->x.regnode->vbl = NULL;
    761         offset = 68;
    762         maxargoffset = 24;
    763         reg = 0;
    764         for (i = 0; callee[i]; i++) {
    765                 Symbol p = callee[i], q = caller[i];
    766                 int size = roundup(q->type->size, 4);
    767                 assert(q);
    768                 if (isfloat(p->type) || reg >= 6) {
    769                         p->x.offset = q->x.offset = offset;
    770                         p->x.name = q->x.name = stringd(offset);
    771                         p->sclass = q->sclass = AUTO;
    772                         autos++;
    773                 }
    774                 else if (p->addressed || varargs) {
    775                         p->x.offset = offset;
    776                         p->x.name = stringd(p->x.offset);
    777                         p->sclass = AUTO;
    778                         q->sclass = REGISTER;
    779                         askregvar(q, ireg[reg]);
    780                         assert(q->x.regnode);
    781                         autos++;
    782                 }
    783                 else {
    784                         p->sclass = q->sclass = REGISTER;
    785                         askregvar(p, ireg[reg]);
    786                         assert(p->x.regnode);
    787                         q->x.name = p->x.name;
    788                 }
    789                 offset += size;
    790                 reg += isstruct(p->type) ? 1 : size/4;
    791         }
    792         assert(caller[i] == 0);
    793         offset = maxoffset = 0;
    794         retstruct = isstruct(freturn(f->type));
    795         gencode(caller, callee);
    796         maxargoffset = roundup(maxargoffset, 4);
    797         framesize = roundup(maxoffset + maxargoffset + 4*(16+1), 8);
    798         assert(!varargs || autos);
    799         leaf = (!ncalls
    800                 && !maxoffset && !autos && !regvars
    801                 && !isstruct(freturn(f->type))
    802                 && !(usedmask[IREG]&0x00ffff01)
    803                 && !(usedmask[FREG]&~(unsigned)3)
    804                 && !pflag && !glevel);
    805         print(".align 4\n%s:\n", f->x.name);
    806         if (leaf) {
    807                 for (i = 0; caller[i] && callee[i]; i++) {
    808                         Symbol p = caller[i], q = callee[i];
    809                         if (p->sclass == REGISTER && q->sclass == REGISTER) {
    810                                 assert(q->x.regnode);
    811                                 assert(q->x.regnode->set == IREG);
    812                                 assert(q->x.regnode->number >= 24);
    813                                 assert(q->x.regnode->number <= 31);
    814                                 p->x.name = greg[q->x.regnode->number - 16]->x.name;
    815                         }
    816                 }
    817                 renameregs();
    818         } else if (framesize <= 4095)
    819                 print("save %%sp,%d,%%sp\n", -framesize);
    820         else
    821                 print("set %d,%%g1; save %%sp,%%g1,%%sp\n", -framesize);
    822         if (varargs)
    823                 for (; reg < 6; reg++)
    824                         print("st %%i%d,[%%fp+%d]\n", reg, 4*reg + 68);
    825         else {
    826                 offset = 4*(16 + 1);
    827                 reg = 0;
    828                 for (i = 0; caller[i]; i++) {
    829                         Symbol p = caller[i];
    830                         if (isfloat(p->type) && p->type->size == 8 && reg <= 4) {
    831                                 print("st %%r%d,[%%fp+%d]\n",
    832                                         ireg[reg++]->x.regnode->number, offset);
    833                                 print("st %%r%d,[%%fp+%d]\n",
    834                                         ireg[reg++]->x.regnode->number, offset + 4);
    835                         } else if (isfloat(p->type) && p->type->size == 4 && reg <= 5)
    836                                 print("st %%r%d,[%%fp+%d]\n",
    837                                         ireg[reg++]->x.regnode->number, offset);
    838                         else
    839                                 reg++;
    840                         offset += roundup(p->type->size, 4);
    841                 }
    842         }
    843         if (pflag) {
    844                 int lab = genlabel(1);
    845                 print("set L%d,%%o0; call mcount; nop\n", lab);
    846                 print(".seg \"data\"\n.align 4; L%d:.word 0\n.seg \"text\"\n", lab);
    847         }
    848         emitcode();
    849         if (isstruct(freturn(f->type)))
    850                 print("jmp %%i7+12; restore\n");
    851         else if (!leaf)
    852                 print("ret; restore\n");
    853         else {
    854                 renameregs();
    855                 print("retl; nop\n");
    856         }
    857         if (IR == &solarisIR) {
    858                 print(".type %s,#function\n", f->x.name);
    859                 print(".size %s,.-%s\n", f->x.name, f->x.name);
    860         }
    861 }
    862 #define exch(x, y, t) (((t) = x), ((x) = (y)), ((y) = (t)))
    863 
    864 static void renameregs(void) {
    865         int i;
    866 
    867         for (i = 0; i < 8; i++) {
    868                 char *ptmp;
    869                 int itmp;
    870                 if (ireg[i]->x.regnode->vbl)
    871                         ireg[i]->x.regnode->vbl->x.name = oreg[i]->x.name;
    872                 exch(ireg[i]->x.name, oreg[i]->x.name, ptmp);
    873                 exch(ireg[i]->x.regnode->number,
    874                         oreg[i]->x.regnode->number, itmp);
    875         }
    876 }
    877 static void defconst(int suffix, int size, Value v) {
    878         if (suffix == F && size == 4) {
    879                 float f = v.d;
    880                 print(".word 0x%x\n", *(unsigned *)&f);
    881         } else if (suffix == F && size == 8) {
    882                 double d = v.d;
    883                 unsigned *p = (unsigned *)&d;
    884                 print(".word 0x%x\n.word 0x%x\n", p[swap], p[!swap]);
    885         } else if (suffix == P)
    886                 print(".word 0x%x\n", v.p);
    887         else if (size == 1)
    888                 print(".byte 0x%x\n", suffix == I ? v.i : v.u);
    889         else if (size == 2)
    890                 print(".half 0x%x\n", suffix == I ? v.i : v.u);
    891         else if (size == 4)
    892                 print(".word 0x%x\n", suffix == I ? v.i : v.u);
    893         else assert(0);
    894 }
    895 
    896 static void defaddress(Symbol p) {
    897         print(".word %s\n", p->x.name);
    898 }
    899 
    900 static void defstring(int n, char *str) {
    901         char *s;
    902 
    903         for (s = str; s < str + n; s++)
    904                 print(".byte %d\n", (*s)&0377);
    905 }
    906 
    907 static void address(Symbol q, Symbol p, long n) {
    908         if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN)
    909                 q->x.name = stringf("%s%s%D", p->x.name, n >= 0 ? "+" : "", n);
    910         else {
    911                 assert(n <= INT_MAX && n >= INT_MIN);
    912                 q->x.offset = p->x.offset + n;
    913                 q->x.name = stringd(q->x.offset);
    914         }
    915 }
    916 static void export(Symbol p) {
    917         print(".global %s\n", p->x.name);
    918 }
    919 static void import(Symbol p) {}
    920 static void defsymbol(Symbol p) {
    921         if (p->scope >= LOCAL && p->sclass == STATIC)
    922                 p->x.name = stringf("%d", genlabel(1));
    923         else
    924                 assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)),
    925                 p->x.name = p->name;
    926         if (p->scope >= LABELS)
    927                 p->x.name = stringf(p->generated ? "L%s" : "_%s",
    928                         p->x.name);
    929 }
    930 static void segment(int n) {
    931         cseg = n;
    932         switch (n) {
    933         case CODE: print(".seg \"text\"\n"); break;
    934         case BSS:  print(".seg \"bss\"\n");  break;
    935         case DATA: print(".seg \"data\"\n"); break;
    936         case LIT:  print(".seg \"text\"\n"); break;
    937         }
    938 }
    939 static void space(int n) {
    940         if (cseg != BSS)
    941                 print(".skip %d\n", n);
    942 }
    943 static void global(Symbol p) {
    944         print(".align %d\n", p->type->align);
    945         assert(p->u.seg);
    946         if (p->u.seg == BSS
    947         && (p->sclass == STATIC || Aflag >= 2))
    948                 print(".reserve %s,%d\n", p->x.name, p->type->size);
    949         else if (p->u.seg == BSS)
    950                 print(".common %s,%d\n",  p->x.name, p->type->size);
    951         else
    952                 print("%s:\n", p->x.name);
    953 }
    954 static void blkfetch(int k, int off, int reg, int tmp) {
    955         assert(k == 1 || k == 2 || k == 4);
    956         assert(salign >= k);
    957         if (k == 1)
    958                 print("ldub [%%r%d+%d],%%r%d\n", reg, off, tmp);
    959         else if (k == 2)
    960                 print("lduh [%%r%d+%d],%%r%d\n", reg, off, tmp);
    961         else
    962                 print("ld [%%r%d+%d],%%r%d\n",   reg, off, tmp);
    963 }
    964 static void blkstore(int k, int off, int reg, int tmp) {
    965         assert(k == 1 || k == 2 || k == 4);
    966         assert(dalign >= k);
    967         if (k == 1)
    968                 print("stb %%r%d,[%%r%d+%d]\n", tmp, reg, off);
    969         else if (k == 2)
    970                 print("sth %%r%d,[%%r%d+%d]\n", tmp, reg, off);
    971         else
    972                 print("st %%r%d,[%%r%d+%d]\n",  tmp, reg, off);
    973 }
    974 static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) {
    975         if ((size&~7) < 4096) {
    976                 print("add %%r%d,%d,%%r%d\n", sreg, size&~7, sreg);
    977                 print("add %%r%d,%d,%%r%d\n", dreg, size&~7, tmps[2]);
    978         } else {
    979                 print("set %d,%%r%d\n", size&~7, tmps[2]);
    980                 print("add %%r%d,%%r%d,%%r%d\n", sreg, tmps[2], sreg);
    981                 print("add %%r%d,%%r%d,%%r%d\n", dreg, tmps[2], tmps[2]);
    982         }
    983         blkcopy(tmps[2], doff, sreg, soff, size&7, tmps);
    984         print("1: dec 8,%%r%d\n", tmps[2]);
    985         blkcopy(tmps[2], doff, sreg, soff - 8, 8, tmps);
    986         print("cmp %%r%d,%%r%d; ", tmps[2], dreg);
    987         print("bgt 1b; ");
    988         print("dec 8,%%r%d\n", sreg);
    989 }
    990 static void defsymbol2(Symbol p) {
    991         if (p->scope >= LOCAL && p->sclass == STATIC)
    992                 p->x.name = stringf(".%d", genlabel(1));
    993         else
    994                 assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)),
    995                 p->x.name = p->name;
    996         if (p->scope >= LABELS)
    997                 p->x.name = stringf(p->generated ? ".L%s" : "%s",
    998                         p->x.name);
    999 }
   1000 
   1001 static Symbol prevg;
   1002 
   1003 static void globalend(void) {
   1004         if (prevg && prevg->type->size > 0)
   1005                 print(".size %s,%d\n", prevg->x.name, prevg->type->size);
   1006         prevg = NULL;
   1007 }
   1008 
   1009 static void export2(Symbol p) {
   1010         globalend();
   1011         print(".global %s\n", p->x.name);
   1012 }
   1013 
   1014 static void progend2(void) {
   1015         globalend();
   1016 }
   1017 
   1018 static void global2(Symbol p) {
   1019         globalend();
   1020         assert(p->u.seg);
   1021         if (!p->generated) {
   1022                 print(".type %s,#%s\n", p->x.name,
   1023                         isfunc(p->type) ? "function" : "object");
   1024                 if (p->type->size > 0)
   1025                         print(".size %s,%d\n", p->x.name, p->type->size);
   1026                 else
   1027                         prevg = p;
   1028         }
   1029         if (p->u.seg == BSS && p->sclass == STATIC)
   1030                 print(".local %s\n.common %s,%d,%d\n", p->x.name, p->x.name,
   1031                         p->type->size, p->type->align);
   1032         else if (p->u.seg == BSS && Aflag >= 2)
   1033                 print(".align %d\n%s:.skip %d\n", p->type->align, p->x.name,
   1034                         p->type->size);
   1035         else if (p->u.seg == BSS)
   1036                 print(".common %s,%d,%d\n", p->x.name, p->type->size, p->type->align);
   1037         else
   1038                 print(".align %d\n%s:\n", p->type->align, p->x.name);
   1039 }
   1040 
   1041 static void segment2(int n) {
   1042         cseg = n;
   1043         switch (n) {
   1044         case CODE: print(".section \".text\"\n");   break;
   1045         case BSS:  print(".section \".bss\"\n");    break;
   1046         case DATA: print(".section \".data\"\n");   break;
   1047         case LIT:  print(".section \".rodata\"\n"); break;
   1048         }
   1049 }
   1050 Interface sparcIR = {
   1051         1, 1, 0,  /* char */
   1052         2, 2, 0,  /* short */
   1053         4, 4, 0,  /* int */
   1054         4, 4, 0,  /* long */
   1055         4, 4, 0,  /* long long */
   1056         4, 4, 1,  /* float */
   1057         8, 8, 1,  /* double */
   1058         8, 8, 1,  /* long double */
   1059         4, 4, 0,  /* T * */
   1060         0, 1, 0,  /* struct */
   1061         0,  /* little_endian */
   1062         0,  /* mulops_calls */
   1063         1,  /* wants_callb */
   1064         0,  /* wants_argb */
   1065         1,  /* left_to_right */
   1066         0,  /* wants_dag */
   1067         0,  /* unsigned_char */
   1068         address,
   1069         blockbeg,
   1070         blockend,
   1071         defaddress,
   1072         defconst,
   1073         defstring,
   1074         defsymbol,
   1075         emit,
   1076         export,
   1077         function,
   1078         gen,
   1079         global,
   1080         import,
   1081         local,
   1082         progbeg,
   1083         progend,
   1084         segment,
   1085         space,
   1086         stabblock, 0, 0, stabinit, stabline, stabsym, stabtype,
   1087         {
   1088                 1,  /* max_unaligned_load */
   1089                 rmap,
   1090                 blkfetch, blkstore, blkloop,
   1091                 _label,
   1092                 _rule,
   1093                 _nts,
   1094                 _kids,
   1095                 _string,
   1096                 _templates,
   1097                 _isinstruction,
   1098                 _ntname,
   1099                 emit2,
   1100                 doarg,
   1101                 target,
   1102                 clobber,
   1103 
   1104         }
   1105 };
   1106 
   1107 Interface solarisIR = {
   1108         1, 1, 0,  /* char */
   1109         2, 2, 0,  /* short */
   1110         4, 4, 0,  /* int */
   1111         4, 4, 0,  /* long */
   1112         4, 4, 0,  /* long long */
   1113         4, 4, 1,  /* float */
   1114         8, 8, 1,  /* double */
   1115         8, 8, 1,  /* long double */
   1116         4, 4, 0,  /* T * */
   1117         0, 1, 0,  /* struct */
   1118         0,      /* little_endian */
   1119         0,      /* mulops_calls */
   1120         1,      /* wants_callb */
   1121         0,      /* wants_argb */
   1122         1,      /* left_to_right */
   1123         0,      /* wants_dag */
   1124         0,      /* unsigned_char */
   1125         address,
   1126         blockbeg,
   1127         blockend,
   1128         defaddress,
   1129         defconst,
   1130         defstring,
   1131         defsymbol2,
   1132         emit,
   1133         export2,
   1134         function,
   1135         gen,
   1136         global2,
   1137         import,
   1138         local,
   1139         progbeg,
   1140         progend2,
   1141         segment2,
   1142         space,
   1143         stabblock, 0, 0, stabinit, stabline, stabsym, stabtype,
   1144         {
   1145                 1,      /* max_unaligned_load */
   1146                 rmap,
   1147                 blkfetch, blkstore, blkloop,
   1148                 _label,
   1149                 _rule,
   1150                 _nts,
   1151                 _kids,
   1152                 _string,
   1153                 _templates,
   1154                 _isinstruction,
   1155                 _ntname,
   1156                 emit2,
   1157                 doarg,
   1158                 target,
   1159                 clobber,
   1160 
   1161         }
   1162 };
   1163 static char rcsid[] = "$Id: sparc.md 145 2001-10-17 21:53:10Z timo $";