insn.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*
  2. * Mnemonic instruction bytecode
  3. *
  4. * Copyright (C) 2005-2007 Peter Johnson
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
  19. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "util.h"
  28. #include "libyasm-stdint.h"
  29. #include "coretype.h"
  30. #include "errwarn.h"
  31. #include "expr.h"
  32. #include "value.h"
  33. #include "bytecode.h"
  34. #include "insn.h"
  35. #include "arch.h"
  36. void
  37. yasm_ea_set_segreg(yasm_effaddr *ea, uintptr_t segreg)
  38. {
  39. if (!ea)
  40. return;
  41. if (segreg != 0 && ea->segreg != 0)
  42. yasm_warn_set(YASM_WARN_GENERAL,
  43. N_("multiple segment overrides, using leftmost"));
  44. ea->segreg = segreg;
  45. }
  46. yasm_insn_operand *
  47. yasm_operand_create_reg(uintptr_t reg)
  48. {
  49. yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
  50. retval->type = YASM_INSN__OPERAND_REG;
  51. retval->data.reg = reg;
  52. retval->seg = 0;
  53. retval->targetmod = 0;
  54. retval->size = 0;
  55. retval->deref = 0;
  56. retval->strict = 0;
  57. return retval;
  58. }
  59. yasm_insn_operand *
  60. yasm_operand_create_segreg(uintptr_t segreg)
  61. {
  62. yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
  63. retval->type = YASM_INSN__OPERAND_SEGREG;
  64. retval->data.reg = segreg;
  65. retval->seg = 0;
  66. retval->targetmod = 0;
  67. retval->size = 0;
  68. retval->deref = 0;
  69. retval->strict = 0;
  70. return retval;
  71. }
  72. yasm_insn_operand *
  73. yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea)
  74. {
  75. yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
  76. retval->type = YASM_INSN__OPERAND_MEMORY;
  77. retval->data.ea = ea;
  78. retval->seg = 0;
  79. retval->targetmod = 0;
  80. retval->size = 0;
  81. retval->deref = 0;
  82. retval->strict = 0;
  83. retval->size = ea->data_len * 8;
  84. return retval;
  85. }
  86. yasm_insn_operand *
  87. yasm_operand_create_imm(/*@only@*/ yasm_expr *val)
  88. {
  89. yasm_insn_operand *retval;
  90. const uintptr_t *reg;
  91. reg = yasm_expr_get_reg(&val, 0);
  92. if (reg) {
  93. retval = yasm_operand_create_reg(*reg);
  94. yasm_expr_destroy(val);
  95. } else {
  96. retval = yasm_xmalloc(sizeof(yasm_insn_operand));
  97. retval->type = YASM_INSN__OPERAND_IMM;
  98. retval->data.val = val;
  99. retval->seg = 0;
  100. retval->targetmod = 0;
  101. retval->size = 0;
  102. retval->deref = 0;
  103. retval->strict = 0;
  104. }
  105. return retval;
  106. }
  107. yasm_insn_operand *
  108. yasm_insn_ops_append(yasm_insn *insn, yasm_insn_operand *op)
  109. {
  110. if (op) {
  111. insn->num_operands++;
  112. STAILQ_INSERT_TAIL(&insn->operands, op, link);
  113. return op;
  114. }
  115. return (yasm_insn_operand *)NULL;
  116. }
  117. void
  118. yasm_insn_add_prefix(yasm_insn *insn, uintptr_t prefix)
  119. {
  120. insn->prefixes =
  121. yasm_xrealloc(insn->prefixes,
  122. (insn->num_prefixes+1)*sizeof(uintptr_t));
  123. insn->prefixes[insn->num_prefixes] = prefix;
  124. insn->num_prefixes++;
  125. }
  126. void
  127. yasm_insn_add_seg_prefix(yasm_insn *insn, uintptr_t segreg)
  128. {
  129. insn->segregs =
  130. yasm_xrealloc(insn->segregs, (insn->num_segregs+1)*sizeof(uintptr_t));
  131. insn->segregs[insn->num_segregs] = segreg;
  132. insn->num_segregs++;
  133. }
  134. void
  135. yasm_insn_initialize(yasm_insn *insn)
  136. {
  137. STAILQ_INIT(&insn->operands);
  138. insn->prefixes = NULL;
  139. insn->segregs = NULL;
  140. insn->num_operands = 0;
  141. insn->num_prefixes = 0;
  142. insn->num_segregs = 0;
  143. }
  144. void
  145. yasm_insn_delete(yasm_insn *insn,
  146. void (*ea_destroy) (/*@only@*/ yasm_effaddr *))
  147. {
  148. if (insn->num_operands > 0) {
  149. yasm_insn_operand *cur, *next;
  150. cur = STAILQ_FIRST(&insn->operands);
  151. while (cur) {
  152. next = STAILQ_NEXT(cur, link);
  153. switch (cur->type) {
  154. case YASM_INSN__OPERAND_MEMORY:
  155. ea_destroy(cur->data.ea);
  156. break;
  157. case YASM_INSN__OPERAND_IMM:
  158. yasm_expr_destroy(cur->data.val);
  159. break;
  160. default:
  161. break;
  162. }
  163. yasm_xfree(cur);
  164. cur = next;
  165. }
  166. }
  167. if (insn->num_prefixes > 0)
  168. yasm_xfree(insn->prefixes);
  169. if (insn->num_segregs > 0)
  170. yasm_xfree(insn->segregs);
  171. }
  172. void
  173. yasm_insn_print(const yasm_insn *insn, FILE *f, int indent_level)
  174. {
  175. const yasm_insn_operand *op;
  176. STAILQ_FOREACH (op, &insn->operands, link) {
  177. switch (op->type) {
  178. case YASM_INSN__OPERAND_REG:
  179. fprintf(f, "%*sReg=", indent_level, "");
  180. /*yasm_arch_reg_print(arch, op->data.reg, f);*/
  181. fprintf(f, "\n");
  182. break;
  183. case YASM_INSN__OPERAND_SEGREG:
  184. fprintf(f, "%*sSegReg=", indent_level, "");
  185. /*yasm_arch_segreg_print(arch, op->data.reg, f);*/
  186. fprintf(f, "\n");
  187. break;
  188. case YASM_INSN__OPERAND_MEMORY:
  189. fprintf(f, "%*sMemory=\n", indent_level, "");
  190. /*yasm_arch_ea_print(arch, op->data.ea, f, indent_level);*/
  191. break;
  192. case YASM_INSN__OPERAND_IMM:
  193. fprintf(f, "%*sImm=", indent_level, "");
  194. yasm_expr_print(op->data.val, f);
  195. fprintf(f, "\n");
  196. break;
  197. }
  198. fprintf(f, "%*sTargetMod=%lx\n", indent_level+1, "",
  199. (unsigned long)op->targetmod);
  200. fprintf(f, "%*sSize=%u\n", indent_level+1, "", op->size);
  201. fprintf(f, "%*sDeref=%d, Strict=%d\n", indent_level+1, "",
  202. (int)op->deref, (int)op->strict);
  203. }
  204. }
  205. void
  206. yasm_insn_finalize(yasm_insn *insn)
  207. {
  208. unsigned int i;
  209. yasm_insn_operand *op;
  210. yasm_error_class eclass;
  211. char *str, *xrefstr;
  212. unsigned long xrefline;
  213. /* Simplify the operands' expressions first. */
  214. for (i = 0, op = yasm_insn_ops_first(insn);
  215. op && i<insn->num_operands; op = yasm_insn_op_next(op), i++) {
  216. /* Check operand type */
  217. switch (op->type) {
  218. case YASM_INSN__OPERAND_MEMORY:
  219. /* Don't get over-ambitious here; some archs' memory expr
  220. * parser are sensitive to the presence of *1, etc, so don't
  221. * simplify reg*1 identities.
  222. */
  223. if (op->data.ea)
  224. op->data.ea->disp.abs =
  225. yasm_expr__level_tree(op->data.ea->disp.abs, 1, 1, 0,
  226. 0, NULL, NULL);
  227. if (yasm_error_occurred()) {
  228. /* Add a pointer to where it was used to the error */
  229. yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
  230. if (xrefstr) {
  231. yasm_error_set_xref(xrefline, "%s", xrefstr);
  232. yasm_xfree(xrefstr);
  233. }
  234. if (str) {
  235. yasm_error_set(eclass, "%s in memory expression", str);
  236. yasm_xfree(str);
  237. }
  238. return;
  239. }
  240. break;
  241. case YASM_INSN__OPERAND_IMM:
  242. op->data.val =
  243. yasm_expr__level_tree(op->data.val, 1, 1, 1, 0, NULL,
  244. NULL);
  245. if (yasm_error_occurred()) {
  246. /* Add a pointer to where it was used to the error */
  247. yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
  248. if (xrefstr) {
  249. yasm_error_set_xref(xrefline, "%s", xrefstr);
  250. yasm_xfree(xrefstr);
  251. }
  252. if (str) {
  253. yasm_error_set(eclass, "%s in immediate expression",
  254. str);
  255. yasm_xfree(str);
  256. }
  257. return;
  258. }
  259. break;
  260. default:
  261. break;
  262. }
  263. }
  264. }