i386-asm.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. /*
  2. * i386 specific functions for TCC assembler
  3. *
  4. * Copyright (c) 2001, 2002 Fabrice Bellard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #define MAX_OPERANDS 3
  21. typedef struct ASMInstr {
  22. uint16_t sym;
  23. uint16_t opcode;
  24. uint16_t instr_type;
  25. #define OPC_JMP 0x01 /* jmp operand */
  26. #define OPC_B 0x02 /* only used zith OPC_WL */
  27. #define OPC_WL 0x04 /* accepts w, l or no suffix */
  28. #define OPC_BWL (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
  29. #define OPC_REG 0x08 /* register is added to opcode */
  30. #define OPC_MODRM 0x10 /* modrm encoding */
  31. #define OPC_FWAIT 0x20 /* add fwait opcode */
  32. #define OPC_TEST 0x40 /* test opcodes */
  33. #define OPC_SHIFT 0x80 /* shift opcodes */
  34. #define OPC_D16 0x0100 /* generate data16 prefix */
  35. #define OPC_ARITH 0x0200 /* arithmetic opcodes */
  36. #define OPC_SHORTJMP 0x0400 /* short jmp operand */
  37. #define OPC_FARITH 0x0800 /* FPU arithmetic opcodes */
  38. #define OPC_GROUP_SHIFT 13
  39. /* in order to compress the operand type, we use specific operands and
  40. we or only with EA */
  41. #define OPT_REG8 0 /* warning: value is hardcoded from TOK_ASM_xxx */
  42. #define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */
  43. #define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */
  44. #define OPT_MMX 3 /* warning: value is hardcoded from TOK_ASM_xxx */
  45. #define OPT_SSE 4 /* warning: value is hardcoded from TOK_ASM_xxx */
  46. #define OPT_CR 5 /* warning: value is hardcoded from TOK_ASM_xxx */
  47. #define OPT_TR 6 /* warning: value is hardcoded from TOK_ASM_xxx */
  48. #define OPT_DB 7 /* warning: value is hardcoded from TOK_ASM_xxx */
  49. #define OPT_SEG 8
  50. #define OPT_ST 9
  51. #define OPT_IM8 10
  52. #define OPT_IM8S 11
  53. #define OPT_IM16 12
  54. #define OPT_IM32 13
  55. #define OPT_EAX 14 /* %al, %ax or %eax register */
  56. #define OPT_ST0 15 /* %st(0) register */
  57. #define OPT_CL 16 /* %cl register */
  58. #define OPT_DX 17 /* %dx register */
  59. #define OPT_ADDR 18 /* OP_EA with only offset */
  60. #define OPT_INDIR 19 /* *(expr) */
  61. /* composite types */
  62. #define OPT_COMPOSITE_FIRST 20
  63. #define OPT_IM 20 /* IM8 | IM16 | IM32 */
  64. #define OPT_REG 21 /* REG8 | REG16 | REG32 */
  65. #define OPT_REGW 22 /* REG16 | REG32 */
  66. #define OPT_IMW 23 /* IM16 | IM32 */
  67. /* can be ored with any OPT_xxx */
  68. #define OPT_EA 0x80
  69. uint8_t nb_ops;
  70. uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
  71. } ASMInstr;
  72. typedef struct Operand {
  73. uint32_t type;
  74. #define OP_REG8 (1 << OPT_REG8)
  75. #define OP_REG16 (1 << OPT_REG16)
  76. #define OP_REG32 (1 << OPT_REG32)
  77. #define OP_MMX (1 << OPT_MMX)
  78. #define OP_SSE (1 << OPT_SSE)
  79. #define OP_CR (1 << OPT_CR)
  80. #define OP_TR (1 << OPT_TR)
  81. #define OP_DB (1 << OPT_DB)
  82. #define OP_SEG (1 << OPT_SEG)
  83. #define OP_ST (1 << OPT_ST)
  84. #define OP_IM8 (1 << OPT_IM8)
  85. #define OP_IM8S (1 << OPT_IM8S)
  86. #define OP_IM16 (1 << OPT_IM16)
  87. #define OP_IM32 (1 << OPT_IM32)
  88. #define OP_EAX (1 << OPT_EAX)
  89. #define OP_ST0 (1 << OPT_ST0)
  90. #define OP_CL (1 << OPT_CL)
  91. #define OP_DX (1 << OPT_DX)
  92. #define OP_ADDR (1 << OPT_ADDR)
  93. #define OP_INDIR (1 << OPT_INDIR)
  94. #define OP_EA 0x40000000
  95. #define OP_REG (OP_REG8 | OP_REG16 | OP_REG32)
  96. #define OP_IM OP_IM32
  97. int8_t reg; /* register, -1 if none */
  98. int8_t reg2; /* second register, -1 if none */
  99. uint8_t shift;
  100. ExprValue e;
  101. } Operand;
  102. static const uint8_t reg_to_size[5] = {
  103. /*
  104. [OP_REG8] = 0,
  105. [OP_REG16] = 1,
  106. [OP_REG32] = 2,
  107. */
  108. 0, 0, 1, 0, 2
  109. };
  110. #define WORD_PREFIX_OPCODE 0x66
  111. #define NB_TEST_OPCODES 30
  112. static const uint8_t test_bits[NB_TEST_OPCODES] = {
  113. 0x00, /* o */
  114. 0x01, /* no */
  115. 0x02, /* b */
  116. 0x02, /* c */
  117. 0x02, /* nae */
  118. 0x03, /* nb */
  119. 0x03, /* nc */
  120. 0x03, /* ae */
  121. 0x04, /* e */
  122. 0x04, /* z */
  123. 0x05, /* ne */
  124. 0x05, /* nz */
  125. 0x06, /* be */
  126. 0x06, /* na */
  127. 0x07, /* nbe */
  128. 0x07, /* a */
  129. 0x08, /* s */
  130. 0x09, /* ns */
  131. 0x0a, /* p */
  132. 0x0a, /* pe */
  133. 0x0b, /* np */
  134. 0x0b, /* po */
  135. 0x0c, /* l */
  136. 0x0c, /* nge */
  137. 0x0d, /* nl */
  138. 0x0d, /* ge */
  139. 0x0e, /* le */
  140. 0x0e, /* ng */
  141. 0x0f, /* nle */
  142. 0x0f, /* g */
  143. };
  144. static const uint8_t segment_prefixes[] = {
  145. 0x26, /* es */
  146. 0x2e, /* cs */
  147. 0x36, /* ss */
  148. 0x3e, /* ds */
  149. 0x64, /* fs */
  150. 0x65 /* gs */
  151. };
  152. static const ASMInstr asm_instrs[] = {
  153. #define ALT(x) x
  154. #define DEF_ASM_OP0(name, opcode)
  155. #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
  156. #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
  157. #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
  158. #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }},
  159. #include "i386-asm.h"
  160. /* last operation */
  161. { 0, },
  162. };
  163. static const uint16_t op0_codes[] = {
  164. #define ALT(x)
  165. #define DEF_ASM_OP0(x, opcode) opcode,
  166. #define DEF_ASM_OP0L(name, opcode, group, instr_type)
  167. #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
  168. #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
  169. #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
  170. #include "i386-asm.h"
  171. };
  172. static inline int get_reg_shift(TCCState *s1)
  173. {
  174. int shift, v;
  175. v = asm_int_expr(s1);
  176. switch(v) {
  177. case 1:
  178. shift = 0;
  179. break;
  180. case 2:
  181. shift = 1;
  182. break;
  183. case 4:
  184. shift = 2;
  185. break;
  186. case 8:
  187. shift = 3;
  188. break;
  189. default:
  190. expect("1, 2, 4 or 8 constant");
  191. shift = 0;
  192. break;
  193. }
  194. return shift;
  195. }
  196. static int asm_parse_reg(void)
  197. {
  198. int reg;
  199. if (tok != '%')
  200. goto error_32;
  201. next();
  202. if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
  203. reg = tok - TOK_ASM_eax;
  204. next();
  205. return reg;
  206. } else {
  207. error_32:
  208. expect("32 bit register");
  209. return 0;
  210. }
  211. }
  212. static void parse_operand(TCCState *s1, Operand *op)
  213. {
  214. ExprValue e;
  215. int reg, indir;
  216. const char *p;
  217. indir = 0;
  218. if (tok == '*') {
  219. next();
  220. indir = OP_INDIR;
  221. }
  222. if (tok == '%') {
  223. next();
  224. if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
  225. reg = tok - TOK_ASM_al;
  226. op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
  227. op->reg = reg & 7;
  228. if ((op->type & OP_REG) && op->reg == TREG_EAX)
  229. op->type |= OP_EAX;
  230. else if (op->type == OP_REG8 && op->reg == TREG_ECX)
  231. op->type |= OP_CL;
  232. else if (op->type == OP_REG16 && op->reg == TREG_EDX)
  233. op->type |= OP_DX;
  234. } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
  235. op->type = OP_DB;
  236. op->reg = tok - TOK_ASM_dr0;
  237. } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
  238. op->type = OP_SEG;
  239. op->reg = tok - TOK_ASM_es;
  240. } else if (tok == TOK_ASM_st) {
  241. op->type = OP_ST;
  242. op->reg = 0;
  243. next();
  244. if (tok == '(') {
  245. next();
  246. if (tok != TOK_PPNUM)
  247. goto reg_error;
  248. p = tokc.cstr->data;
  249. reg = p[0] - '0';
  250. if ((unsigned)reg >= 8 || p[1] != '\0')
  251. goto reg_error;
  252. op->reg = reg;
  253. next();
  254. skip(')');
  255. }
  256. if (op->reg == 0)
  257. op->type |= OP_ST0;
  258. goto no_skip;
  259. } else {
  260. reg_error:
  261. error("unknown register");
  262. }
  263. next();
  264. no_skip: ;
  265. } else if (tok == '$') {
  266. /* constant value */
  267. next();
  268. asm_expr(s1, &e);
  269. op->type = OP_IM32;
  270. op->e.v = e.v;
  271. op->e.sym = e.sym;
  272. if (!op->e.sym) {
  273. if (op->e.v == (uint8_t)op->e.v)
  274. op->type |= OP_IM8;
  275. if (op->e.v == (int8_t)op->e.v)
  276. op->type |= OP_IM8S;
  277. if (op->e.v == (uint16_t)op->e.v)
  278. op->type |= OP_IM16;
  279. }
  280. } else {
  281. /* address(reg,reg2,shift) with all variants */
  282. op->type = OP_EA;
  283. op->reg = -1;
  284. op->reg2 = -1;
  285. op->shift = 0;
  286. if (tok != '(') {
  287. asm_expr(s1, &e);
  288. op->e.v = e.v;
  289. op->e.sym = e.sym;
  290. } else {
  291. op->e.v = 0;
  292. op->e.sym = NULL;
  293. }
  294. if (tok == '(') {
  295. next();
  296. if (tok != ',') {
  297. op->reg = asm_parse_reg();
  298. }
  299. if (tok == ',') {
  300. next();
  301. if (tok != ',') {
  302. op->reg2 = asm_parse_reg();
  303. }
  304. if (tok == ',') {
  305. next();
  306. op->shift = get_reg_shift(s1);
  307. }
  308. }
  309. skip(')');
  310. }
  311. if (op->reg == -1 && op->reg2 == -1)
  312. op->type |= OP_ADDR;
  313. }
  314. op->type |= indir;
  315. }
  316. /* XXX: unify with C code output ? */
  317. static void gen_expr32(ExprValue *pe)
  318. {
  319. if (pe->sym)
  320. greloc(cur_text_section, pe->sym, ind, R_386_32);
  321. gen_le32(pe->v);
  322. }
  323. /* XXX: unify with C code output ? */
  324. static void gen_disp32(ExprValue *pe)
  325. {
  326. Sym *sym;
  327. sym = pe->sym;
  328. if (sym) {
  329. if (sym->r == cur_text_section->sh_num) {
  330. /* same section: we can output an absolute value. Note
  331. that the TCC compiler behaves differently here because
  332. it always outputs a relocation to ease (future) code
  333. elimination in the linker */
  334. gen_le32(pe->v + (long)sym->next - ind - 4);
  335. } else {
  336. greloc(cur_text_section, sym, ind, R_386_PC32);
  337. gen_le32(pe->v - 4);
  338. }
  339. } else {
  340. /* put an empty PC32 relocation */
  341. put_elf_reloc(symtab_section, cur_text_section,
  342. ind, R_386_PC32, 0);
  343. gen_le32(pe->v - 4);
  344. }
  345. }
  346. static void gen_le16(int v)
  347. {
  348. g(v);
  349. g(v >> 8);
  350. }
  351. /* generate the modrm operand */
  352. static inline void asm_modrm(int reg, Operand *op)
  353. {
  354. int mod, reg1, reg2, sib_reg1;
  355. if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
  356. g(0xc0 + (reg << 3) + op->reg);
  357. } else if (op->reg == -1 && op->reg2 == -1) {
  358. /* displacement only */
  359. g(0x05 + (reg << 3));
  360. gen_expr32(&op->e);
  361. } else {
  362. sib_reg1 = op->reg;
  363. /* fist compute displacement encoding */
  364. if (sib_reg1 == -1) {
  365. sib_reg1 = 5;
  366. mod = 0x00;
  367. } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
  368. mod = 0x00;
  369. } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
  370. mod = 0x40;
  371. } else {
  372. mod = 0x80;
  373. }
  374. /* compute if sib byte needed */
  375. reg1 = op->reg;
  376. if (op->reg2 != -1)
  377. reg1 = 4;
  378. g(mod + (reg << 3) + reg1);
  379. if (reg1 == 4) {
  380. /* add sib byte */
  381. reg2 = op->reg2;
  382. if (reg2 == -1)
  383. reg2 = 4; /* indicate no index */
  384. g((op->shift << 6) + (reg2 << 3) + sib_reg1);
  385. }
  386. /* add offset */
  387. if (mod == 0x40) {
  388. g(op->e.v);
  389. } else if (mod == 0x80 || op->reg == -1) {
  390. gen_expr32(&op->e);
  391. }
  392. }
  393. }
  394. static void asm_opcode(TCCState *s1, int opcode)
  395. {
  396. const ASMInstr *pa;
  397. int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix;
  398. int nb_ops, s, ss;
  399. Operand ops[MAX_OPERANDS], *pop;
  400. int op_type[3]; /* decoded op type */
  401. /* get operands */
  402. pop = ops;
  403. nb_ops = 0;
  404. seg_prefix = 0;
  405. for(;;) {
  406. if (tok == ';' || tok == TOK_LINEFEED)
  407. break;
  408. if (nb_ops >= MAX_OPERANDS) {
  409. error("incorrect number of operands");
  410. }
  411. parse_operand(s1, pop);
  412. if (tok == ':') {
  413. if (pop->type != OP_SEG || seg_prefix) {
  414. error("incorrect prefix");
  415. }
  416. seg_prefix = segment_prefixes[pop->reg];
  417. next();
  418. parse_operand(s1, pop);
  419. if (!(pop->type & OP_EA)) {
  420. error("segment prefix must be followed by memory reference");
  421. }
  422. }
  423. pop++;
  424. nb_ops++;
  425. if (tok != ',')
  426. break;
  427. next();
  428. }
  429. is_short_jmp = 0;
  430. s = 0; /* avoid warning */
  431. /* optimize matching by using a lookup table (no hashing is needed
  432. !) */
  433. for(pa = asm_instrs; pa->sym != 0; pa++) {
  434. s = 0;
  435. if (pa->instr_type & OPC_FARITH) {
  436. v = opcode - pa->sym;
  437. if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
  438. continue;
  439. } else if (pa->instr_type & OPC_ARITH) {
  440. if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4))
  441. continue;
  442. goto compute_size;
  443. } else if (pa->instr_type & OPC_SHIFT) {
  444. if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4))
  445. continue;
  446. goto compute_size;
  447. } else if (pa->instr_type & OPC_TEST) {
  448. if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
  449. continue;
  450. } else if (pa->instr_type & OPC_B) {
  451. if (!(opcode >= pa->sym && opcode <= pa->sym + 3))
  452. continue;
  453. compute_size:
  454. s = (opcode - pa->sym) & 3;
  455. } else if (pa->instr_type & OPC_WL) {
  456. if (!(opcode >= pa->sym && opcode <= pa->sym + 2))
  457. continue;
  458. s = opcode - pa->sym + 1;
  459. } else {
  460. if (pa->sym != opcode)
  461. continue;
  462. }
  463. if (pa->nb_ops != nb_ops)
  464. continue;
  465. /* now decode and check each operand */
  466. for(i = 0; i < nb_ops; i++) {
  467. int op1, op2;
  468. op1 = pa->op_type[i];
  469. op2 = op1 & 0x1f;
  470. switch(op2) {
  471. case OPT_IM:
  472. v = OP_IM8 | OP_IM16 | OP_IM32;
  473. break;
  474. case OPT_REG:
  475. v = OP_REG8 | OP_REG16 | OP_REG32;
  476. break;
  477. case OPT_REGW:
  478. v = OP_REG16 | OP_REG32;
  479. break;
  480. case OPT_IMW:
  481. v = OP_IM16 | OP_IM32;
  482. break;
  483. default:
  484. v = 1 << op2;
  485. break;
  486. }
  487. if (op1 & OPT_EA)
  488. v |= OP_EA;
  489. op_type[i] = v;
  490. if ((ops[i].type & v) == 0)
  491. goto next;
  492. }
  493. /* all is matching ! */
  494. break;
  495. next: ;
  496. }
  497. if (pa->sym == 0) {
  498. if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) {
  499. int b;
  500. b = op0_codes[opcode - TOK_ASM_pusha];
  501. if (b & 0xff00)
  502. g(b >> 8);
  503. g(b);
  504. return;
  505. } else {
  506. error("unknown opcode '%s'",
  507. get_tok_str(opcode, NULL));
  508. }
  509. }
  510. /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
  511. if (s == 3) {
  512. for(i = 0; s == 3 && i < nb_ops; i++) {
  513. if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
  514. s = reg_to_size[ops[i].type & OP_REG];
  515. }
  516. if (s == 3) {
  517. if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
  518. (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
  519. s = 2;
  520. else
  521. error("cannot infer opcode suffix");
  522. }
  523. }
  524. /* generate data16 prefix if needed */
  525. ss = s;
  526. if (s == 1 || (pa->instr_type & OPC_D16))
  527. g(WORD_PREFIX_OPCODE);
  528. else if (s == 2)
  529. s = 1;
  530. /* now generates the operation */
  531. if (pa->instr_type & OPC_FWAIT)
  532. g(0x9b);
  533. if (seg_prefix)
  534. g(seg_prefix);
  535. v = pa->opcode;
  536. if (v == 0x69 || v == 0x69) {
  537. /* kludge for imul $im, %reg */
  538. nb_ops = 3;
  539. ops[2] = ops[1];
  540. } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
  541. v--; /* int $3 case */
  542. nb_ops = 0;
  543. } else if ((v == 0x06 || v == 0x07)) {
  544. if (ops[0].reg >= 4) {
  545. /* push/pop %fs or %gs */
  546. v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
  547. } else {
  548. v += ops[0].reg << 3;
  549. }
  550. nb_ops = 0;
  551. } else if (v <= 0x05) {
  552. /* arith case */
  553. v += ((opcode - TOK_ASM_addb) >> 2) << 3;
  554. } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
  555. /* fpu arith case */
  556. v += ((opcode - pa->sym) / 6) << 3;
  557. }
  558. if (pa->instr_type & OPC_REG) {
  559. for(i = 0; i < nb_ops; i++) {
  560. if (op_type[i] & (OP_REG | OP_ST)) {
  561. v += ops[i].reg;
  562. break;
  563. }
  564. }
  565. /* mov $im, %reg case */
  566. if (pa->opcode == 0xb0 && s >= 1)
  567. v += 7;
  568. }
  569. if (pa->instr_type & OPC_B)
  570. v += s;
  571. if (pa->instr_type & OPC_TEST)
  572. v += test_bits[opcode - pa->sym];
  573. if (pa->instr_type & OPC_SHORTJMP) {
  574. Sym *sym;
  575. int jmp_disp;
  576. /* see if we can really generate the jump with a byte offset */
  577. sym = ops[0].e.sym;
  578. if (!sym)
  579. goto no_short_jump;
  580. if (sym->r != cur_text_section->sh_num)
  581. goto no_short_jump;
  582. jmp_disp = ops[0].e.v + (long)sym->next - ind - 2;
  583. if (jmp_disp == (int8_t)jmp_disp) {
  584. /* OK to generate jump */
  585. is_short_jmp = 1;
  586. ops[0].e.v = jmp_disp;
  587. } else {
  588. no_short_jump:
  589. if (pa->instr_type & OPC_JMP) {
  590. /* long jump will be allowed. need to modify the
  591. opcode slightly */
  592. if (v == 0xeb)
  593. v = 0xe9;
  594. else
  595. v += 0x0f10;
  596. } else {
  597. error("invalid displacement");
  598. }
  599. }
  600. }
  601. op1 = v >> 8;
  602. if (op1)
  603. g(op1);
  604. g(v);
  605. /* search which operand will used for modrm */
  606. modrm_index = 0;
  607. if (pa->instr_type & OPC_SHIFT) {
  608. reg = (opcode - pa->sym) >> 2;
  609. if (reg == 6)
  610. reg = 7;
  611. } else if (pa->instr_type & OPC_ARITH) {
  612. reg = (opcode - pa->sym) >> 2;
  613. } else if (pa->instr_type & OPC_FARITH) {
  614. reg = (opcode - pa->sym) / 6;
  615. } else {
  616. reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
  617. }
  618. if (pa->instr_type & OPC_MODRM) {
  619. /* first look for an ea operand */
  620. for(i = 0;i < nb_ops; i++) {
  621. if (op_type[i] & OP_EA)
  622. goto modrm_found;
  623. }
  624. /* then if not found, a register or indirection (shift instructions) */
  625. for(i = 0;i < nb_ops; i++) {
  626. if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
  627. goto modrm_found;
  628. }
  629. #ifdef ASM_DEBUG
  630. error("bad op table");
  631. #endif
  632. modrm_found:
  633. modrm_index = i;
  634. /* if a register is used in another operand then it is
  635. used instead of group */
  636. for(i = 0;i < nb_ops; i++) {
  637. v = op_type[i];
  638. if (i != modrm_index &&
  639. (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
  640. reg = ops[i].reg;
  641. break;
  642. }
  643. }
  644. asm_modrm(reg, &ops[modrm_index]);
  645. }
  646. /* emit constants */
  647. if (pa->opcode == 0x9a || pa->opcode == 0xea) {
  648. /* ljmp or lcall kludge */
  649. gen_expr32(&ops[1].e);
  650. if (ops[0].e.sym)
  651. error("cannot relocate");
  652. gen_le16(ops[0].e.v);
  653. } else {
  654. for(i = 0;i < nb_ops; i++) {
  655. v = op_type[i];
  656. if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) {
  657. /* if multiple sizes are given it means we must look
  658. at the op size */
  659. if (v == (OP_IM8 | OP_IM16 | OP_IM32) ||
  660. v == (OP_IM16 | OP_IM32)) {
  661. if (ss == 0)
  662. v = OP_IM8;
  663. else if (ss == 1)
  664. v = OP_IM16;
  665. else
  666. v = OP_IM32;
  667. }
  668. if (v & (OP_IM8 | OP_IM8S)) {
  669. if (ops[i].e.sym)
  670. goto error_relocate;
  671. g(ops[i].e.v);
  672. } else if (v & OP_IM16) {
  673. if (ops[i].e.sym) {
  674. error_relocate:
  675. error("cannot relocate");
  676. }
  677. gen_le16(ops[i].e.v);
  678. } else {
  679. if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
  680. if (is_short_jmp)
  681. g(ops[i].e.v);
  682. else
  683. gen_disp32(&ops[i].e);
  684. } else {
  685. gen_expr32(&ops[i].e);
  686. }
  687. }
  688. }
  689. }
  690. }
  691. }
  692. #define NB_SAVED_REGS 3
  693. #define NB_ASM_REGS 8
  694. /* return the constraint priority (we allocate first the lowest
  695. numbered constraints) */
  696. static inline int constraint_priority(const char *str)
  697. {
  698. int priority, c, pr;
  699. /* we take the lowest priority */
  700. priority = 0;
  701. for(;;) {
  702. c = *str;
  703. if (c == '\0')
  704. break;
  705. str++;
  706. switch(c) {
  707. case 'A':
  708. pr = 0;
  709. break;
  710. case 'a':
  711. case 'b':
  712. case 'c':
  713. case 'd':
  714. case 'S':
  715. case 'D':
  716. pr = 1;
  717. break;
  718. case 'q':
  719. pr = 2;
  720. break;
  721. case 'r':
  722. pr = 3;
  723. break;
  724. case 'N':
  725. case 'M':
  726. case 'I':
  727. case 'i':
  728. case 'm':
  729. case 'g':
  730. pr = 4;
  731. break;
  732. default:
  733. error("unknown constraint '%c'", c);
  734. pr = 0;
  735. }
  736. if (pr > priority)
  737. priority = pr;
  738. }
  739. return priority;
  740. }
  741. static const char *skip_constraint_modifiers(const char *p)
  742. {
  743. while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
  744. p++;
  745. return p;
  746. }
  747. #define REG_OUT_MASK 0x01
  748. #define REG_IN_MASK 0x02
  749. #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
  750. static void asm_compute_constraints(ASMOperand *operands,
  751. int nb_operands, int nb_outputs,
  752. const uint8_t *clobber_regs,
  753. int *pout_reg)
  754. {
  755. ASMOperand *op;
  756. int sorted_op[MAX_ASM_OPERANDS];
  757. int i, j, k, p1, p2, tmp, reg, c, reg_mask;
  758. const char *str;
  759. uint8_t regs_allocated[NB_ASM_REGS];
  760. /* init fields */
  761. for(i=0;i<nb_operands;i++) {
  762. op = &operands[i];
  763. op->input_index = -1;
  764. op->ref_index = -1;
  765. op->reg = -1;
  766. op->is_memory = 0;
  767. op->is_rw = 0;
  768. }
  769. /* compute constraint priority and evaluate references to output
  770. constraints if input constraints */
  771. for(i=0;i<nb_operands;i++) {
  772. op = &operands[i];
  773. str = op->constraint;
  774. str = skip_constraint_modifiers(str);
  775. if (isnum(*str) || *str == '[') {
  776. /* this is a reference to another constraint */
  777. k = find_constraint(operands, nb_operands, str, NULL);
  778. if ((unsigned)k >= i || i < nb_outputs)
  779. error("invalid reference in constraint %d ('%s')",
  780. i, str);
  781. op->ref_index = k;
  782. if (operands[k].input_index >= 0)
  783. error("cannot reference twice the same operand");
  784. operands[k].input_index = i;
  785. op->priority = 5;
  786. } else {
  787. op->priority = constraint_priority(str);
  788. }
  789. }
  790. /* sort operands according to their priority */
  791. for(i=0;i<nb_operands;i++)
  792. sorted_op[i] = i;
  793. for(i=0;i<nb_operands - 1;i++) {
  794. for(j=i+1;j<nb_operands;j++) {
  795. p1 = operands[sorted_op[i]].priority;
  796. p2 = operands[sorted_op[j]].priority;
  797. if (p2 < p1) {
  798. tmp = sorted_op[i];
  799. sorted_op[i] = sorted_op[j];
  800. sorted_op[j] = tmp;
  801. }
  802. }
  803. }
  804. for(i = 0;i < NB_ASM_REGS; i++) {
  805. if (clobber_regs[i])
  806. regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
  807. else
  808. regs_allocated[i] = 0;
  809. }
  810. /* esp cannot be used */
  811. regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK;
  812. /* ebp cannot be used yet */
  813. regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK;
  814. /* allocate registers and generate corresponding asm moves */
  815. for(i=0;i<nb_operands;i++) {
  816. j = sorted_op[i];
  817. op = &operands[j];
  818. str = op->constraint;
  819. /* no need to allocate references */
  820. if (op->ref_index >= 0)
  821. continue;
  822. /* select if register is used for output, input or both */
  823. if (op->input_index >= 0) {
  824. reg_mask = REG_IN_MASK | REG_OUT_MASK;
  825. } else if (j < nb_outputs) {
  826. reg_mask = REG_OUT_MASK;
  827. } else {
  828. reg_mask = REG_IN_MASK;
  829. }
  830. try_next:
  831. c = *str++;
  832. switch(c) {
  833. case '=':
  834. goto try_next;
  835. case '+':
  836. op->is_rw = 1;
  837. /* FALL THRU */
  838. case '&':
  839. if (j >= nb_outputs)
  840. error("'%c' modifier can only be applied to outputs", c);
  841. reg_mask = REG_IN_MASK | REG_OUT_MASK;
  842. goto try_next;
  843. case 'A':
  844. /* allocate both eax and edx */
  845. if (is_reg_allocated(TREG_EAX) ||
  846. is_reg_allocated(TREG_EDX))
  847. goto try_next;
  848. op->is_llong = 1;
  849. op->reg = TREG_EAX;
  850. regs_allocated[TREG_EAX] |= reg_mask;
  851. regs_allocated[TREG_EDX] |= reg_mask;
  852. break;
  853. case 'a':
  854. reg = TREG_EAX;
  855. goto alloc_reg;
  856. case 'b':
  857. reg = 3;
  858. goto alloc_reg;
  859. case 'c':
  860. reg = TREG_ECX;
  861. goto alloc_reg;
  862. case 'd':
  863. reg = TREG_EDX;
  864. goto alloc_reg;
  865. case 'S':
  866. reg = 6;
  867. goto alloc_reg;
  868. case 'D':
  869. reg = 7;
  870. alloc_reg:
  871. if (is_reg_allocated(reg))
  872. goto try_next;
  873. goto reg_found;
  874. case 'q':
  875. /* eax, ebx, ecx or edx */
  876. for(reg = 0; reg < 4; reg++) {
  877. if (!is_reg_allocated(reg))
  878. goto reg_found;
  879. }
  880. goto try_next;
  881. case 'r':
  882. /* any general register */
  883. for(reg = 0; reg < 8; reg++) {
  884. if (!is_reg_allocated(reg))
  885. goto reg_found;
  886. }
  887. goto try_next;
  888. reg_found:
  889. /* now we can reload in the register */
  890. op->is_llong = 0;
  891. op->reg = reg;
  892. regs_allocated[reg] |= reg_mask;
  893. break;
  894. case 'i':
  895. if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
  896. goto try_next;
  897. break;
  898. case 'I':
  899. case 'N':
  900. case 'M':
  901. if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
  902. goto try_next;
  903. break;
  904. case 'm':
  905. case 'g':
  906. /* nothing special to do because the operand is already in
  907. memory, except if the pointer itself is stored in a
  908. memory variable (VT_LLOCAL case) */
  909. /* XXX: fix constant case */
  910. /* if it is a reference to a memory zone, it must lie
  911. in a register, so we reserve the register in the
  912. input registers and a load will be generated
  913. later */
  914. if (j < nb_outputs || c == 'm') {
  915. if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
  916. /* any general register */
  917. for(reg = 0; reg < 8; reg++) {
  918. if (!(regs_allocated[reg] & REG_IN_MASK))
  919. goto reg_found1;
  920. }
  921. goto try_next;
  922. reg_found1:
  923. /* now we can reload in the register */
  924. regs_allocated[reg] |= REG_IN_MASK;
  925. op->reg = reg;
  926. op->is_memory = 1;
  927. }
  928. }
  929. break;
  930. default:
  931. error("asm constraint %d ('%s') could not be satisfied",
  932. j, op->constraint);
  933. break;
  934. }
  935. /* if a reference is present for that operand, we assign it too */
  936. if (op->input_index >= 0) {
  937. operands[op->input_index].reg = op->reg;
  938. operands[op->input_index].is_llong = op->is_llong;
  939. }
  940. }
  941. /* compute out_reg. It is used to store outputs registers to memory
  942. locations references by pointers (VT_LLOCAL case) */
  943. *pout_reg = -1;
  944. for(i=0;i<nb_operands;i++) {
  945. op = &operands[i];
  946. if (op->reg >= 0 &&
  947. (op->vt->r & VT_VALMASK) == VT_LLOCAL &&
  948. !op->is_memory) {
  949. for(reg = 0; reg < 8; reg++) {
  950. if (!(regs_allocated[reg] & REG_OUT_MASK))
  951. goto reg_found2;
  952. }
  953. error("could not find free output register for reloading");
  954. reg_found2:
  955. *pout_reg = reg;
  956. break;
  957. }
  958. }
  959. /* print sorted constraints */
  960. #ifdef ASM_DEBUG
  961. for(i=0;i<nb_operands;i++) {
  962. j = sorted_op[i];
  963. op = &operands[j];
  964. printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
  965. j,
  966. op->id ? get_tok_str(op->id, NULL) : "",
  967. op->constraint,
  968. op->vt->r,
  969. op->reg);
  970. }
  971. if (*pout_reg >= 0)
  972. printf("out_reg=%d\n", *pout_reg);
  973. #endif
  974. }
  975. static void subst_asm_operand(CString *add_str,
  976. SValue *sv, int modifier)
  977. {
  978. int r, reg, size, val;
  979. char buf[64];
  980. r = sv->r;
  981. if ((r & VT_VALMASK) == VT_CONST) {
  982. if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
  983. cstr_ccat(add_str, '$');
  984. if (r & VT_SYM) {
  985. cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
  986. if (sv->c.i != 0) {
  987. cstr_ccat(add_str, '+');
  988. } else {
  989. return;
  990. }
  991. }
  992. val = sv->c.i;
  993. if (modifier == 'n')
  994. val = -val;
  995. snprintf(buf, sizeof(buf), "%d", sv->c.i);
  996. cstr_cat(add_str, buf);
  997. } else if ((r & VT_VALMASK) == VT_LOCAL) {
  998. snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
  999. cstr_cat(add_str, buf);
  1000. } else if (r & VT_LVAL) {
  1001. reg = r & VT_VALMASK;
  1002. if (reg >= VT_CONST)
  1003. error("internal compiler error");
  1004. snprintf(buf, sizeof(buf), "(%%%s)",
  1005. get_tok_str(TOK_ASM_eax + reg, NULL));
  1006. cstr_cat(add_str, buf);
  1007. } else {
  1008. /* register case */
  1009. reg = r & VT_VALMASK;
  1010. if (reg >= VT_CONST)
  1011. error("internal compiler error");
  1012. /* choose register operand size */
  1013. if ((sv->type.t & VT_BTYPE) == VT_BYTE)
  1014. size = 1;
  1015. else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
  1016. size = 2;
  1017. else
  1018. size = 4;
  1019. if (size == 1 && reg >= 4)
  1020. size = 4;
  1021. if (modifier == 'b') {
  1022. if (reg >= 4)
  1023. error("cannot use byte register");
  1024. size = 1;
  1025. } else if (modifier == 'h') {
  1026. if (reg >= 4)
  1027. error("cannot use byte register");
  1028. size = -1;
  1029. } else if (modifier == 'w') {
  1030. size = 2;
  1031. }
  1032. switch(size) {
  1033. case -1:
  1034. reg = TOK_ASM_ah + reg;
  1035. break;
  1036. case 1:
  1037. reg = TOK_ASM_al + reg;
  1038. break;
  1039. case 2:
  1040. reg = TOK_ASM_ax + reg;
  1041. break;
  1042. default:
  1043. reg = TOK_ASM_eax + reg;
  1044. break;
  1045. }
  1046. snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
  1047. cstr_cat(add_str, buf);
  1048. }
  1049. }
  1050. /* generate prolog and epilog code for asm statement */
  1051. static void asm_gen_code(ASMOperand *operands, int nb_operands,
  1052. int nb_outputs, int is_output,
  1053. uint8_t *clobber_regs,
  1054. int out_reg)
  1055. {
  1056. uint8_t regs_allocated[NB_ASM_REGS];
  1057. ASMOperand *op;
  1058. int i, reg;
  1059. static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
  1060. /* mark all used registers */
  1061. memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
  1062. for(i = 0; i < nb_operands;i++) {
  1063. op = &operands[i];
  1064. if (op->reg >= 0)
  1065. regs_allocated[op->reg] = 1;
  1066. }
  1067. if (!is_output) {
  1068. /* generate reg save code */
  1069. for(i = 0; i < NB_SAVED_REGS; i++) {
  1070. reg = reg_saved[i];
  1071. if (regs_allocated[reg])
  1072. g(0x50 + reg);
  1073. }
  1074. /* generate load code */
  1075. for(i = 0; i < nb_operands; i++) {
  1076. op = &operands[i];
  1077. if (op->reg >= 0) {
  1078. if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
  1079. op->is_memory) {
  1080. /* memory reference case (for both input and
  1081. output cases) */
  1082. SValue sv;
  1083. sv = *op->vt;
  1084. sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
  1085. load(op->reg, &sv);
  1086. } else if (i >= nb_outputs || op->is_rw) {
  1087. /* load value in register */
  1088. load(op->reg, op->vt);
  1089. if (op->is_llong) {
  1090. SValue sv;
  1091. sv = *op->vt;
  1092. sv.c.ul += 4;
  1093. load(TREG_EDX, &sv);
  1094. }
  1095. }
  1096. }
  1097. }
  1098. } else {
  1099. /* generate save code */
  1100. for(i = 0 ; i < nb_outputs; i++) {
  1101. op = &operands[i];
  1102. if (op->reg >= 0) {
  1103. if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
  1104. if (!op->is_memory) {
  1105. SValue sv;
  1106. sv = *op->vt;
  1107. sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
  1108. load(out_reg, &sv);
  1109. sv.r = (sv.r & ~VT_VALMASK) | out_reg;
  1110. store(op->reg, &sv);
  1111. }
  1112. } else {
  1113. store(op->reg, op->vt);
  1114. if (op->is_llong) {
  1115. SValue sv;
  1116. sv = *op->vt;
  1117. sv.c.ul += 4;
  1118. store(TREG_EDX, &sv);
  1119. }
  1120. }
  1121. }
  1122. }
  1123. /* generate reg restore code */
  1124. for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
  1125. reg = reg_saved[i];
  1126. if (regs_allocated[reg])
  1127. g(0x58 + reg);
  1128. }
  1129. }
  1130. }
  1131. static void asm_clobber(uint8_t *clobber_regs, const char *str)
  1132. {
  1133. int reg;
  1134. TokenSym *ts;
  1135. if (!strcmp(str, "memory") ||
  1136. !strcmp(str, "cc"))
  1137. return;
  1138. ts = tok_alloc(str, strlen(str));
  1139. reg = ts->tok;
  1140. if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
  1141. reg -= TOK_ASM_eax;
  1142. } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
  1143. reg -= TOK_ASM_ax;
  1144. } else {
  1145. error("invalid clobber register '%s'", str);
  1146. }
  1147. clobber_regs[reg] = 1;
  1148. }