x86nasm.md
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:21k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. %{
  2. enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 };
  3. #include "c.h"
  4. #define NODEPTR_TYPE Node
  5. #define OP_LABEL(p) ((p)->op)
  6. #define LEFT_CHILD(p) ((p)->kids[0])
  7. #define RIGHT_CHILD(p) ((p)->kids[1])
  8. #define STATE_LABEL(p) ((p)->x.state)
  9. static void address     ARGS((Symbol, Symbol, int));
  10. static void blkfetch    ARGS((int, int, int, int));
  11. static void blkloop     ARGS((int, int, int, int, int, int[]));
  12. static void blkstore    ARGS((int, int, int, int));
  13. static void defaddress  ARGS((Symbol));
  14. static void defconst    ARGS((int, Value));
  15. static void defstring   ARGS((int, char *));
  16. static void defsymbol   ARGS((Symbol));
  17. static void doarg       ARGS((Node));
  18. static void emit2       ARGS((Node));
  19. static void export      ARGS((Symbol));
  20. static void clobber     ARGS((Node));
  21. static void function    ARGS((Symbol, Symbol [], Symbol [], int));
  22. static void global      ARGS((Symbol));
  23. static void import      ARGS((Symbol));
  24. static void local       ARGS((Symbol));
  25. static void progbeg     ARGS((int, char **));
  26. static void progend     ARGS((void));
  27. static void segment     ARGS((int));
  28. static void space       ARGS((int));
  29. static void target      ARGS((Node));
  30. static int ckstack ARGS((Node, int));
  31. static int memop ARGS((Node));
  32. static int sametree ARGS((Node, Node));
  33. static Symbol charreg[32], shortreg[32], intreg[32];
  34. static Symbol fltreg[32];
  35. static int cseg;
  36. static Symbol quo, rem;
  37. %}
  38. %start stmt
  39. %term ADDD=306 ADDF=305 ADDI=309 ADDP=311 ADDU=310
  40. %term ADDRFP=279
  41. %term ADDRGP=263
  42. %term ADDRLP=295
  43. %term ARGB=41 ARGD=34 ARGF=33 ARGI=37 ARGP=39
  44. %term ASGNB=57 ASGNC=51 ASGND=50 ASGNF=49 ASGNI=53 ASGNP=55 ASGNS=52
  45. %term BANDU=390
  46. %term BCOMU=406
  47. %term BORU=422
  48. %term BXORU=438
  49. %term CALLB=217 CALLD=210 CALLF=209 CALLI=213 CALLV=216
  50. %term CNSTC=19 CNSTD=18 CNSTF=17 CNSTI=21 CNSTP=23 CNSTS=20 CNSTU=22
  51. %term CVCI=85 CVCU=86
  52. %term CVDF=97 CVDI=101
  53. %term CVFD=114
  54. %term CVIC=131 CVID=130 CVIS=132 CVIU=134
  55. %term CVPU=150
  56. %term CVSI=165 CVSU=166
  57. %term CVUC=179 CVUI=181 CVUP=183 CVUS=180
  58. %term DIVD=450 DIVF=449 DIVI=453 DIVU=454
  59. %term EQD=482 EQF=481 EQI=485
  60. %term GED=498 GEF=497 GEI=501 GEU=502
  61. %term GTD=514 GTF=513 GTI=517 GTU=518
  62. %term INDIRB=73 INDIRC=67 INDIRD=66 INDIRF=65 INDIRI=69 INDIRP=71 INDIRS=68
  63. %term JUMPV=584
  64. %term LABELV=600
  65. %term LED=530 LEF=529 LEI=533 LEU=534
  66. %term LOADB=233 LOADC=227 LOADD=226 LOADF=225 LOADI=229 LOADP=231 LOADS=228 LOADU=230
  67. %term LSHI=341 LSHU=342
  68. %term LTD=546 LTF=545 LTI=549 LTU=550
  69. %term MODI=357 MODU=358
  70. %term MULD=466 MULF=465 MULI=469 MULU=470
  71. %term NED=562 NEF=561 NEI=565
  72. %term NEGD=194 NEGF=193 NEGI=197
  73. %term RETD=242 RETF=241 RETI=245
  74. %term RSHI=373 RSHU=374
  75. %term SUBD=322 SUBF=321 SUBI=325 SUBP=327 SUBU=326
  76. %term VREGP=615
  77. %%
  78. reg:  INDIRC(VREGP)     "# read registern"
  79. reg:  INDIRD(VREGP)     "# read registern"
  80. reg:  INDIRF(VREGP)     "# read registern"
  81. reg:  INDIRI(VREGP)     "# read registern"
  82. reg:  INDIRP(VREGP)     "# read registern"
  83. reg:  INDIRS(VREGP)     "# read registern"
  84. stmt: ASGNC(VREGP,reg)  "# write registern"
  85. stmt: ASGND(VREGP,reg)  "# write registern"
  86. stmt: ASGNF(VREGP,reg)  "# write registern"
  87. stmt: ASGNI(VREGP,reg)  "# write registern"
  88. stmt: ASGNP(VREGP,reg)  "# write registern"
  89. stmt: ASGNS(VREGP,reg)  "# write registern"
  90. con: CNSTC  "%a"
  91. con: CNSTI  "%a"
  92. con: CNSTP  "%a"
  93. con: CNSTS  "%a"
  94. con: CNSTU  "%a"
  95. stmt: reg  ""
  96. reg: CVIU(reg)  "%0"  notarget(a)
  97. reg: CVPU(reg)  "%0"  notarget(a)
  98. reg: CVUI(reg)  "%0"  notarget(a)
  99. reg: CVUP(reg)  "%0"  notarget(a)
  100. acon: ADDRGP  "%a"
  101. acon: con     "%0"
  102. base: ADDRGP          "%a"
  103. base: reg             "%0"
  104. base: ADDI(reg,acon)  "%0 + (%1)"
  105. base: ADDP(reg,acon)  "%0 + (%1)"
  106. base: ADDU(reg,acon)  "%0 + (%1)"
  107. base: ADDRFP  "ebp + %a"
  108. base: ADDRLP  "ebp + %a"
  109. index: reg "%0"
  110. index: LSHI(reg,con1)  "%0*2"
  111. index: LSHI(reg,con2)  "%0*4"
  112. index: LSHI(reg,con3)  "%0*8"
  113. con1:  CNSTI  "1"  range(a, 1, 1)
  114. con1:  CNSTU  "1"  range(a, 1, 1)
  115. con2:  CNSTI  "2"  range(a, 2, 2)
  116. con2:  CNSTU  "2"  range(a, 2, 2)
  117. con3:  CNSTI  "3"  range(a, 3, 3)
  118. con3:  CNSTU  "3"  range(a, 3, 3)
  119. index: LSHU(reg,con1)  "%0*2"
  120. index: LSHU(reg,con2)  "%0*4"
  121. index: LSHU(reg,con3)  "%0*8"
  122. addr: base              "[%0]"
  123. addr: ADDI(index,base)  "[%1 + %0]"
  124. addr: ADDP(index,base)  "[%1 + %0]"
  125. addr: ADDU(index,base)  "[%1 + %0]"
  126. addr: index  "[%0]"
  127. mem: INDIRC(addr)  "byte %0"
  128. mem: INDIRI(addr)  "dword %0"
  129. mem: INDIRP(addr)  "dword %0"
  130. mem: INDIRS(addr)  "word %0"
  131. rc:   reg  "%0"
  132. rc:   con  "%0"
  133. mr:   reg  "%0"
  134. mr:   mem  "%0"
  135. mrc0: mem  "%0"
  136. mrc0: rc   "%0"
  137. mrc1: mem  "%0"  1
  138. mrc1: rc   "%0"
  139. mrc3: mem  "%0"  3
  140. mrc3: rc   "%0"
  141. reg: addr        "lea %c,%0n"  1
  142. reg: mrc0        "mov %c,%0n"  1
  143. reg: LOADC(reg)  "mov %c,%0n"  move(a)
  144. reg: LOADI(reg)  "mov %c,%0n"  move(a)
  145. reg: LOADP(reg)  "mov %c,%0n"  move(a)
  146. reg: LOADS(reg)  "mov %c,%0n"  move(a)
  147. reg: LOADU(reg)  "mov %c,%0n"  move(a)
  148. reg: ADDI(reg,mrc1)  "?mov %c,%0nadd %c,%1n"  1
  149. reg: ADDP(reg,mrc1)  "?mov %c,%0nadd %c,%1n"  1
  150. reg: ADDU(reg,mrc1)  "?mov %c,%0nadd %c,%1n"  1
  151. reg: SUBI(reg,mrc1)  "?mov %c,%0nsub %c,%1n"  1
  152. reg: SUBP(reg,mrc1)  "?mov %c,%0nsub %c,%1n"  1
  153. reg: SUBU(reg,mrc1)  "?mov %c,%0nsub %c,%1n"  1
  154. reg: BANDU(reg,mrc1)  "?mov %c,%0nand %c,%1n"  1
  155. reg: BORU(reg,mrc1)   "?mov %c,%0nor %c,%1n"   1
  156. reg: BXORU(reg,mrc1)  "?mov %c,%0nxor %c,%1n"  1
  157. stmt: ASGNI(addr,ADDI(mem,con1))  "inc %1n"  memop(a)
  158. stmt: ASGNI(addr,ADDU(mem,con1))  "inc %1n"  memop(a)
  159. stmt: ASGNP(addr,ADDP(mem,con1))  "inc %1n"  memop(a)
  160. stmt: ASGNI(addr,SUBI(mem,con1))  "dec %1n"  memop(a)
  161. stmt: ASGNI(addr,SUBU(mem,con1))  "dec %1n"  memop(a)
  162. stmt: ASGNP(addr,SUBP(mem,con1))  "dec %1n"  memop(a)
  163. stmt: ASGNI(addr,ADDI(mem,rc))   "add %1,%2n"  memop(a)
  164. stmt: ASGNI(addr,ADDU(mem,rc))   "add %1,%2n"  memop(a)
  165. stmt: ASGNI(addr,SUBI(mem,rc))   "sub %1,%2n"  memop(a)
  166. stmt: ASGNI(addr,SUBU(mem,rc))   "sub %1,%2n"  memop(a)
  167. stmt: ASGNI(addr,BANDU(mem,rc))  "and %1,%2n"  memop(a)
  168. stmt: ASGNI(addr,BORU(mem,rc))   "or %1,%2n"   memop(a)
  169. stmt: ASGNI(addr,BXORU(mem,rc))  "xor %1,%2n"  memop(a)
  170. reg: BCOMU(reg)  "?mov %c,%0nnot %cn"  2
  171. reg: NEGI(reg)   "?mov %c,%0nneg %cn"  2
  172. stmt: ASGNI(addr,BCOMU(mem))  "not %1n"  memop(a)
  173. stmt: ASGNI(addr,NEGI(mem))   "neg %1n"  memop(a)
  174. reg: LSHI(reg,rc5)  "?mov %c,%0nsal %c,%1n"  2
  175. reg: LSHU(reg,rc5)  "?mov %c,%0nshl %c,%1n"  2
  176. reg: RSHI(reg,rc5)  "?mov %c,%0nsar %c,%1n"  2
  177. reg: RSHU(reg,rc5)  "?mov %c,%0nshr %c,%1n"  2
  178. stmt: ASGNI(addr,LSHI(mem,rc5))  "sal %1,%2n"  memop(a)
  179. stmt: ASGNI(addr,LSHU(mem,rc5))  "shl %1,%2n"  memop(a)
  180. stmt: ASGNI(addr,RSHI(mem,rc5))  "sar %1,%2n"  memop(a)
  181. stmt: ASGNI(addr,RSHU(mem,rc5))  "shr %1,%2n"  memop(a)
  182. rc5: CNSTI  "%a"  range(a, 0, 31)
  183. rc5: reg    "cl"
  184. reg: MULI(reg,mrc3)  "?mov %c,%0nimul %c,%1n"  14
  185. reg: MULI(con,mr)    "imul %c,%1,%0n"  13
  186. reg: MULU(reg,mr)  "mul %1n"  13
  187. reg: DIVU(reg,reg)  "xor edx,edxndiv %1n"
  188. reg: MODU(reg,reg)  "xor edx,edxndiv %1n"
  189. reg: DIVI(reg,reg)  "cdqnidiv %1n"
  190. reg: MODI(reg,reg)  "cdqnidiv %1n"
  191. reg: CVIU(reg)  "mov %c,%0n"  move(a)
  192. reg: CVPU(reg)  "mov %c,%0n"  move(a)
  193. reg: CVUI(reg)  "mov %c,%0n"  move(a)
  194. reg: CVUP(reg)  "mov %c,%0n"  move(a)
  195. reg: CVCI(INDIRC(addr))  "movsx %c,byte %0n"  3
  196. reg: CVCU(INDIRC(addr))  "movzx %c,byte %0n"  3
  197. reg: CVSI(INDIRS(addr))  "movsx %c,word %0n"  3
  198. reg: CVSU(INDIRS(addr))  "movzx %c,word %0n"  3
  199. reg: CVCI(reg)  "# extendn"  3
  200. reg: CVCU(reg)  "# extendn"  3
  201. reg: CVSI(reg)  "# extendn"  3
  202. reg: CVSU(reg)  "# extendn"  3
  203. reg: CVIC(reg)  "# truncaten"  1
  204. reg: CVIS(reg)  "# truncaten"  1
  205. reg: CVUC(reg)  "# truncaten"  1
  206. reg: CVUS(reg)  "# truncaten"  1
  207. stmt: ASGNC(addr,rc)  "mov byte %0,%1n"   1
  208. stmt: ASGNI(addr,rc)  "mov dword %0,%1n"  1
  209. stmt: ASGNP(addr,rc)  "mov dword %0,%1n"  1
  210. stmt: ASGNS(addr,rc)  "mov word %0,%1n"   1
  211. stmt: ARGI(mrc3)  "push dword %0n"  1
  212. stmt: ARGP(mrc3)  "push dword %0n"  1
  213. stmt: ASGNB(reg,INDIRB(reg))  "mov ecx,%anrep movsbn"
  214. stmt: ARGB(INDIRB(reg))  "sub esp,%anmov edi,espnmov ecx,%anrep movsbn"
  215. memf: INDIRD(addr)        "qword %0"
  216. memf: INDIRF(addr)        "dword %0"
  217. memf: CVFD(INDIRF(addr))  "dword %0"
  218. reg: memf  "fld %0n"  3
  219. stmt: ASGND(addr,reg)        "fstp qword %0n"  7
  220. stmt: ASGNF(addr,reg)        "fstp dword %0n"  7
  221. stmt: ASGNF(addr,CVDF(reg))  "fstp dword %0n"  7
  222. stmt: ARGD(reg)  "sub esp,8nfstp qword [esp]n"
  223. stmt: ARGF(reg)  "sub esp,4nfstp dword [esp]n"
  224. reg: NEGD(reg)  "fchsn"
  225. reg: NEGF(reg)  "fchsn"
  226. reg: ADDD(reg,memf)  "fadd %1n"
  227. reg: ADDD(reg,reg)  "faddp st1n"
  228. reg: ADDF(reg,memf)  "fadd %1n"
  229. reg: ADDF(reg,reg)  "faddp st1n"
  230. reg: DIVD(reg,memf)  "fdiv %1n"
  231. reg: DIVD(reg,reg)  "fdivp st1n"
  232. reg: DIVF(reg,memf)  "fdiv %1n"
  233. reg: DIVF(reg,reg)  "fdivp st1n"
  234. reg: MULD(reg,memf)  "fmul %1n"
  235. reg: MULD(reg,reg)  "fmulp st1n"
  236. reg: MULF(reg,memf)  "fmul %1n"
  237. reg: MULF(reg,reg)  "fmulp st1n"
  238. reg: SUBD(reg,memf)  "fsub %1n"
  239. reg: SUBD(reg,reg)  "fsubp st1n"
  240. reg: SUBF(reg,memf)  "fsub %1n"
  241. reg: SUBF(reg,reg)  "fsubp st1n"
  242. reg: CVFD(reg)  "# CVFDn"
  243. reg: CVDF(reg)  "sub esp,4nfstp dword [esp]nfld dword [esp]nadd esp,4n"  12
  244. stmt: ASGNI(addr,CVDI(reg))  "fistp dword %0n"  29
  245. reg: CVDI(reg)  "sub esp,4nfistp dword [esp]npop %cn" 31
  246. reg: CVID(INDIRI(addr))  "fild dword %0n"  10
  247. reg: CVID(reg)  "push %0nfild dword [esp]nadd esp,4n"  12
  248. addrj: ADDRGP  "%a"
  249. addrj: reg     "%0"  2
  250. addrj: mem     "%0"  2
  251. stmt:  JUMPV(addrj)  "jmp %0n"  3
  252. stmt:  LABELV        "%a:n"
  253. stmt: EQI(mem,rc)  "cmp %0,%1nje near %an"   5
  254. stmt: GEI(mem,rc)  "cmp %0,%1njge near %an"  5
  255. stmt: GTI(mem,rc)  "cmp %0,%1njg near %an"   5
  256. stmt: LEI(mem,rc)  "cmp %0,%1njle near %an"  5
  257. stmt: LTI(mem,rc)  "cmp %0,%1njl near %an"   5
  258. stmt: NEI(mem,rc)  "cmp %0,%1njne near %an"  5
  259. stmt: GEU(mem,rc)  "cmp %0,%1njae near %an"  5
  260. stmt: GTU(mem,rc)  "cmp %0,%1nja  near %an"  5
  261. stmt: LEU(mem,rc)  "cmp %0,%1njbe near %an"  5
  262. stmt: LTU(mem,rc)  "cmp %0,%1njb  near %an"  5
  263. stmt: EQI(reg,mrc1)  "cmp %0,%1nje near %an"   4
  264. stmt: GEI(reg,mrc1)  "cmp %0,%1njge near %an"  4
  265. stmt: GTI(reg,mrc1)  "cmp %0,%1njg near %an"   4
  266. stmt: LEI(reg,mrc1)  "cmp %0,%1njle near %an"  4
  267. stmt: LTI(reg,mrc1)  "cmp %0,%1njl near %an"   4
  268. stmt: NEI(reg,mrc1)  "cmp %0,%1njne near %an"  4
  269. stmt: GEU(reg,mrc1)  "cmp %0,%1njae near %an"  4
  270. stmt: GTU(reg,mrc1)  "cmp %0,%1nja near %an"   4
  271. stmt: LEU(reg,mrc1)  "cmp %0,%1njbe near %an"  4
  272. stmt: LTU(reg,mrc1)  "cmp %0,%1njb near %an"   4
  273. cmpf: memf  " %0"
  274. cmpf: reg   "p"
  275. stmt: EQD(cmpf,reg)  "fcomp%0nfstsw axnsahfnje near %an"
  276. stmt: GED(cmpf,reg)  "fcomp%0nfstsw axnsahfnjbe near %an"
  277. stmt: GTD(cmpf,reg)  "fcomp%0nfstsw axnsahfnjb near %an"
  278. stmt: LED(cmpf,reg)  "fcomp%0nfstsw axnsahfnjae near %an"
  279. stmt: LTD(cmpf,reg)  "fcomp%0nfstsw axnsahfnja near %an"
  280. stmt: NED(cmpf,reg)  "fcomp%0nfstsw axnsahfnjne near %an"
  281. stmt: EQF(cmpf,reg)  "fcomp%0nfstsw axnsahfnje near %an"
  282. stmt: GEF(cmpf,reg)  "fcomp%0nfstsw axnsahfnjbe near %an"
  283. stmt: GTF(cmpf,reg)  "fcomp%0nfstsw axnsahfnjb near %an"
  284. stmt: LEF(cmpf,reg)  "fcomp%0nfstsw axnsahfnjae near %an"
  285. stmt: LTF(cmpf,reg)  "fcomp%0nfstsw axnsahfnja near %an"
  286. stmt: NEF(cmpf,reg)  "fcomp%0nfstsw axnsahfnjne near %an"
  287. reg:  CALLI(addrj)  "call %0nadd esp,%an"
  288. stmt: CALLV(addrj)  "call %0nadd esp,%an"
  289. reg: CALLF(addrj)  "call %0nadd esp,%an"
  290. reg: CALLD(addrj)  "call %0nadd esp,%an"
  291. stmt: RETI(reg)  "# retn"
  292. stmt: RETF(reg)  "# retn"
  293. stmt: RETD(reg)  "# retn"
  294. %%
  295. static void progbeg(argc, argv) int argc; char *argv[]; {
  296. int i;
  297. {
  298. union {
  299. char c;
  300. int i;
  301. } u;
  302. u.i = 0;
  303. u.c = 1;
  304. swap = (u.i == 1) != IR->little_endian;
  305. }
  306. parseflags(argc, argv);
  307. intreg[EAX] = mkreg("eax", EAX, 1, IREG);
  308. intreg[EDX] = mkreg("edx", EDX, 1, IREG);
  309. intreg[ECX] = mkreg("ecx", ECX, 1, IREG);
  310. intreg[EBX] = mkreg("ebx", EBX, 1, IREG);
  311. intreg[ESI] = mkreg("esi", ESI, 1, IREG);
  312. intreg[EDI] = mkreg("edi", EDI, 1, IREG);
  313. shortreg[EAX] = mkreg("ax", EAX, 1, IREG);
  314. shortreg[ECX] = mkreg("cx", ECX, 1, IREG);
  315. shortreg[EDX] = mkreg("dx", EDX, 1, IREG);
  316. shortreg[EBX] = mkreg("bx", EBX, 1, IREG);
  317. shortreg[ESI] = mkreg("si", ESI, 1, IREG);
  318. shortreg[EDI] = mkreg("di", EDI, 1, IREG);
  319. charreg[EAX]  = mkreg("al", EAX, 1, IREG);
  320. charreg[ECX]  = mkreg("cl", ECX, 1, IREG);
  321. charreg[EDX]  = mkreg("dl", EDX, 1, IREG);
  322. charreg[EBX]  = mkreg("bl", EBX, 1, IREG);
  323. for (i = 0; i < 8; i++)
  324. fltreg[i] = mkreg("%d", i, 0, FREG);
  325. rmap[C] = mkwildcard(charreg);
  326. rmap[S] = mkwildcard(shortreg);
  327. rmap[P] = rmap[B] = rmap[U] = rmap[I] = mkwildcard(intreg);
  328. rmap[F] = rmap[D] = mkwildcard(fltreg);
  329. tmask[IREG] = (1<<EDI) | (1<<ESI) | (1<<EBX)
  330.             | (1<<EDX) | (1<<ECX) | (1<<EAX);
  331. vmask[IREG] = 0;
  332. tmask[FREG] = 0xff;
  333. vmask[FREG] = 0;
  334. cseg = 0;
  335. quo = mkreg("eax", EAX, 1, IREG);
  336. quo->x.regnode->mask |= 1<<EDX;
  337. rem = mkreg("edx", EDX, 1, IREG);
  338. rem->x.regnode->mask |= 1<<EAX;
  339. }
  340. static void segment(n) int n; {
  341. if (n == cseg)
  342. return;
  343. cseg = n;
  344. if (cseg == CODE)
  345. print("[section .text]n");
  346. else if (cseg == DATA || cseg == LIT)
  347. print("[section .data]n");
  348. else if (cseg == BSS)
  349. print("[section .bss]n");
  350. }
  351. static void progend() {
  352. }
  353. static void target(p) Node p; {
  354. assert(p);
  355. switch (p->op) {
  356. case RSHI: case RSHU: case LSHI: case LSHU:
  357. if (generic(p->kids[1]->op) != CNST
  358. && !(   generic(p->kids[1]->op) == INDIR
  359.      && p->kids[1]->kids[0]->op == VREG+P
  360.      && p->kids[1]->syms[RX]->u.t.cse
  361.      && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST
  362. )) {
  363. rtarget(p, 1, intreg[ECX]);
  364. setreg(p, intreg[EAX]);
  365. }
  366. break;
  367. case MULU:
  368. setreg(p, quo);
  369. rtarget(p, 0, intreg[EAX]);
  370. break;
  371. case DIVI: case DIVU:
  372. setreg(p, quo);
  373. rtarget(p, 0, intreg[EAX]);
  374. rtarget(p, 1, intreg[ECX]);
  375. break;
  376. case MODI: case MODU:
  377. setreg(p, rem);
  378. rtarget(p, 0, intreg[EAX]);
  379. rtarget(p, 1, intreg[ECX]);
  380. break;
  381. case ASGNB:
  382. rtarget(p, 0, intreg[EDI]);
  383. rtarget(p->kids[1], 0, intreg[ESI]);
  384. break;
  385. case ARGB:
  386. rtarget(p->kids[0], 0, intreg[ESI]);
  387. break;
  388. case CALLI: case CALLV:
  389. setreg(p, intreg[EAX]);
  390. break;
  391. case RETI:
  392. rtarget(p, 0, intreg[EAX]);
  393. break;
  394. }
  395. }
  396. static void clobber(p) Node p; {
  397. static int nstack = 0;
  398. assert(p);
  399. nstack = ckstack(p, nstack);
  400. assert(p->count > 0 || nstack == 0);
  401. switch (p->op) {
  402. case ASGNB: case ARGB:
  403. spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p);
  404. break;
  405. case EQD: case LED: case GED: case LTD: case GTD: case NED:
  406. case EQF: case LEF: case GEF: case LTF: case GTF: case NEF:
  407. spill(1<<EAX, IREG, p);
  408. break;
  409. case CALLD: case CALLF:
  410. spill(1<<EDX | 1<<EAX, IREG, p);
  411. break;
  412. }
  413. }
  414. #define isfp(p) (optype((p)->op)==F || optype((p)->op)==D)
  415. static int ckstack(p, n) Node p; int n; {
  416. int i;
  417. for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
  418. if (isfp(p->x.kids[i]))
  419. n--;
  420. if (isfp(p) && p->count > 0)
  421. n++;
  422. if (n > 8)
  423. error("expression too complicatedn");
  424. debug(fprint(2, "(ckstack(%x)=%d)n", p, n));
  425. assert(n >= 0);
  426. return n;
  427. }
  428. static int memop(p) Node p; {
  429. assert(p);
  430. assert(generic(p->op) == ASGN);
  431. assert(p->kids[0]);
  432. assert(p->kids[1]);
  433. if (generic(p->kids[1]->kids[0]->op) == INDIR
  434. && sametree(p->kids[0], p->kids[1]->kids[0]->kids[0]))
  435. return 3;
  436. else
  437. return LBURG_MAX;
  438. }
  439. static int sametree(p, q) Node p, q; {
  440. return p == NULL && q == NULL
  441. || p && q && p->op == q->op && p->syms[0] == q->syms[0]
  442. && sametree(p->kids[0], q->kids[0])
  443. && sametree(p->kids[1], q->kids[1]);
  444. }
  445. static void emit2(p) Node p; {
  446. #define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name)
  447. if (p->op == CVCI)
  448. print("movsx %s,%sn", p->syms[RX]->x.name
  449. , preg(charreg));
  450. else if (p->op == CVCU)
  451. print("movzx %s,%sn", p->syms[RX]->x.name
  452. , preg(charreg));
  453. else if (p->op == CVSI)
  454. print("movsx %s,%sn", p->syms[RX]->x.name
  455. , preg(shortreg));
  456. else if (p->op == CVSU)
  457. print("movzx %s,%sn", p->syms[RX]->x.name
  458. , preg(shortreg));
  459. else if (p->op == CVIC || p->op == CVIS
  460.       || p->op == CVUC || p->op == CVUS) {
  461. char *dst = shortreg[getregnum(p)]->x.name;
  462. char *src = preg(shortreg);
  463. if (dst != src)
  464. print("mov %s,%sn", dst, src);
  465. }
  466. }
  467. static void doarg(p) Node p; {
  468. assert(p && p->syms[0]);
  469. mkactual(4, p->syms[0]->u.c.v.i);
  470. }
  471. static void blkfetch(k, off, reg, tmp)
  472. int k, off, reg, tmp; {}
  473. static void blkstore(k, off, reg, tmp)
  474. int k, off, reg, tmp; {}
  475. static void blkloop(dreg, doff, sreg, soff, size, tmps)
  476. int dreg, doff, sreg, soff, size, tmps[]; {}
  477. static void local(p) Symbol p; {
  478. if (isfloat(p->type))
  479. p->sclass = AUTO;
  480. if (askregvar(p, rmap[ttob(p->type)]) == 0)
  481. mkauto(p);
  482. }
  483. static void function(f, caller, callee, n)
  484. Symbol f, callee[], caller[]; int n; {
  485. int i;
  486. print("%s:n", f->x.name);
  487. print("push ebxn");
  488. print("push esin");
  489. print("push edin");
  490. print("push ebpn");
  491. print("mov ebp,espn");
  492. usedmask[0] = usedmask[1] = 0;
  493. freemask[0] = freemask[1] = ~(unsigned)0;
  494. offset = 16 + 4;
  495. for (i = 0; callee[i]; i++) {
  496. Symbol p = callee[i];
  497. Symbol q = caller[i];
  498. assert(q);
  499. p->x.offset = q->x.offset = offset;
  500. p->x.name = q->x.name = stringf("%d", p->x.offset);
  501. p->sclass = q->sclass = AUTO;
  502. offset += roundup(q->type->size, 4);
  503. }
  504. assert(caller[i] == 0);
  505. offset = maxoffset = 0;
  506. gencode(caller, callee);
  507. framesize = roundup(maxoffset, 4);
  508. if (framesize > 0)
  509. print("sub esp,%dn", framesize);
  510. emitcode();
  511. print("mov esp,ebpn");
  512. print("pop ebpn");
  513. print("pop edin");
  514. print("pop esin");
  515. print("pop ebxn");
  516. print("retn");
  517. }
  518. static void defsymbol(p) Symbol p; {
  519. if (p->scope >= LOCAL && p->sclass == STATIC)
  520. p->x.name = stringf("L%d", genlabel(1));
  521. else if (p->generated)
  522. p->x.name = stringf("$L%s", p->name);
  523. else if (p->scope == GLOBAL || p->sclass == EXTERN)
  524. /* CHANGE THIS FOR a.out */
  525. #if 0
  526. p->x.name = stringf("$_%s", p->name);
  527. #else
  528. p->x.name = stringf("$%s", p->name);
  529. #endif
  530. else if (p->scope == CONSTANTS
  531. && (isint(p->type) || isptr(p->type))
  532. && p->name[0] == '0' && p->name[1] == 'x')
  533. p->x.name = stringf("0%sH", &p->name[2]);
  534. else
  535. p->x.name = p->name;
  536. }
  537. static void address(q, p, n) Symbol q, p; int n; {
  538. if (p->scope == GLOBAL
  539. || p->sclass == STATIC || p->sclass == EXTERN)
  540. q->x.name = stringf("%s%s%d",
  541. p->x.name, n >= 0 ? "+" : "", n);
  542. else {
  543. q->x.offset = p->x.offset + n;
  544. q->x.name = stringd(q->x.offset);
  545. }
  546. }
  547. static void defconst(ty, v) int ty; Value v; {
  548. switch (ty) {
  549. case C: print("db %dn",   v.uc); return;
  550. case S: print("dw %dn",   v.ss); return;
  551. case I: print("dd %dn",   v.i ); return;
  552. case U: print("dd 0%xHn", v.u ); return;
  553. case P: print("dd 0%xHn", v.p ); return;
  554. case F:
  555. print("dd 0%xHn", *(unsigned *)&v.f);
  556. return;
  557. case D: {
  558. unsigned *p = (unsigned *)&v.d;
  559. print("dd 0%xH,0%xHn", p[swap], p[1 - swap]);
  560. return;
  561. }
  562. }
  563. assert(0);
  564. }
  565. static void defaddress(p) Symbol p; {
  566. print("dd %sn", p->x.name);
  567. }
  568. static void defstring(n, str) int n; char *str; {
  569. char *s;
  570. int inquote = 1;
  571. print("db '");
  572. for (s = str; s < str + n; s++)
  573. {
  574. if ((*s & 0x7F) == *s && *s >= ' ' && *s != ''') {
  575. if (!inquote){
  576. print(", '");
  577. inquote = 1;
  578. }
  579. print("%c",*s);
  580. }
  581. else
  582. {
  583. if (inquote){
  584. print("', ");
  585. inquote = 0;
  586. }
  587. else
  588. print(", ");
  589. print("%d",*s);
  590. }
  591. }
  592. if (inquote) print("'");
  593. print("n");
  594. }
  595. static void export(p) Symbol p; {
  596. print("[global %s]n", p->x.name);
  597. }
  598. static void import(p) Symbol p; {
  599. if (p->ref > 0) {
  600. print("[extern %s]n", p->x.name);
  601. }
  602. }
  603. static void global(p) Symbol p; {
  604. int i;
  605. if (p->u.seg == BSS)
  606. print("resb ($-$$) & %dn",
  607. p->type->align > 4 ? 3 : p->type->align-1);
  608. else
  609. print("times ($-$$) & %d nopn",
  610. p->type->align > 4 ? 3 : p->type->align-1);
  611. print("%s:n", p->x.name);
  612. if (p->u.seg == BSS)
  613. print("resb %dn", p->type->size);
  614. }
  615. static void space(n) int n; {
  616. int i;
  617. if (cseg != BSS)
  618. print("times %d db 0n", n);
  619. }
  620. Interface x86nasmIR = {
  621. 1, 1, 0,  /* char */
  622. 2, 2, 0,  /* short */
  623. 4, 4, 0,  /* int */
  624. 4, 4, 1,  /* float */
  625. 8, 4, 1,  /* double */
  626. 4, 4, 0,  /* T * */
  627. 0, 4, 0,  /* struct; so that ARGB keeps stack aligned */
  628. 1,        /* little_endian */
  629. 0,        /* mulops_calls */
  630. 0,        /* wants_callb */
  631. 1,        /* wants_argb */
  632. 0,        /* left_to_right */
  633. 0,        /* wants_dag */
  634. address,
  635. blockbeg,
  636. blockend,
  637. defaddress,
  638. defconst,
  639. defstring,
  640. defsymbol,
  641. emit,
  642. export,
  643. function,
  644. gen,
  645. global,
  646. import,
  647. local,
  648. progbeg,
  649. progend,
  650. segment,
  651. space,
  652. 0, 0, 0, 0, 0, 0, 0,
  653. {1, blkfetch, blkstore, blkloop,
  654.     _label,
  655.     _rule,
  656.     _nts,
  657.     _kids,
  658.     _opname,
  659.     _arity,
  660.     _string,
  661.     _templates,
  662.     _isinstruction,
  663.     _ntname,
  664.     emit2,
  665.     doarg,
  666.     target,
  667.     clobber,
  668. }
  669. };