as.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #include "arg_type.h"
  2. #include "as.h"
  3. #define last( s) ( s + strlen( s) - 1)
  4. #define LEFT '('
  5. #define RIGHT ')'
  6. #define DOLLAR '$'
  7. block_assemble( instr, nr, first, Last)
  8. char **instr;
  9. int nr, first, Last;
  10. {
  11. int i;
  12. /*
  13. if ( first) {
  14. if( strncmp( instr[0], "pop", 3) == 0) {
  15. *instr[0] = 'P';
  16. *( instr[0]+1) = 'O';
  17. *( instr[0]+2) = 'P';
  18. }
  19. else
  20. @clean_push_buf();
  21. }
  22. if ( Last && strncmp( instr[nr-1], "push", 4) == 0) {
  23. *instr[nr-1] = 'P';
  24. *( instr[nr-1]+1) = 'U';
  25. *( instr[nr-1]+2) = 'S';
  26. *( instr[nr-1]+3) = 'H';
  27. }
  28. */
  29. for( i=0; i<nr; i++)
  30. assemble( instr[i]);
  31. }
  32. process_label( l)
  33. char *l;
  34. {
  35. }
  36. process_mnemonic( m)
  37. char *m;
  38. {
  39. }
  40. process_operand( str, op)
  41. char *str;
  42. struct t_operand *op;
  43. /* expr -> IS_DATA en IS_LABEL
  44. * reg -> IS_REG en IS_ACCU
  45. * (expr) -> IS_ADDR
  46. * expr(reg) -> IS_MEM
  47. */
  48. {
  49. char *ptr, *strchr();
  50. op->type = UNKNOWN;
  51. if ( *last( str) == RIGHT) {
  52. ptr = strchr( str, LEFT);
  53. *last( str) = '\0';
  54. *ptr = '\0';
  55. if ( is_reg( ptr+1, op)) {
  56. op->type = IS_MEM;
  57. op->expr = ( *str == '\0' ? "0" : str);
  58. }
  59. else {
  60. set_label( ptr+1, op);
  61. op->type = IS_ADDR;
  62. }
  63. }
  64. else
  65. if ( is_reg( str, op))
  66. op->type = IS_REG;
  67. else {
  68. if ( contains_label( str))
  69. set_label( str, op);
  70. else {
  71. op->type = IS_DATA;
  72. op->expr = str;
  73. }
  74. }
  75. }
  76. static struct regnam {
  77. char *regstr;
  78. int regval;
  79. } regnam[] = {
  80. { "eax", 0 },
  81. { "ebx", 3 },
  82. { "ecx", 1 },
  83. { "edx", 2 },
  84. { "esp", 4 },
  85. { "ebp", 5 },
  86. { "esi", 6 },
  87. { "edi", 7 },
  88. { "al", 0 },
  89. { "bl", 3 },
  90. { "cl", 1 },
  91. { "dl", 2 },
  92. { "ah", 4 },
  93. { "bh", 7 },
  94. { "ch", 5 },
  95. { "dh", 6 },
  96. { 0, 0}
  97. }
  98. ;
  99. int is_reg( str, op)
  100. char *str;
  101. struct t_operand *op;
  102. {
  103. register struct regnam *p = regnam;
  104. while (p->regstr) {
  105. if (! strcmp(p->regstr, str)) {
  106. op->reg = p->regval;
  107. return TRUE;
  108. }
  109. p++;
  110. }
  111. return FALSE;
  112. }
  113. #include <ctype.h>
  114. #define isletter( c) ( isalpha( c) || c == '_')
  115. int contains_label( str)
  116. char *str;
  117. {
  118. while( !isletter( *str) && *str != '\0')
  119. if ( *str == '$')
  120. if ( arg_type( str) == STRING)
  121. return( TRUE);
  122. else
  123. str += 2;
  124. else
  125. str++;
  126. return( isletter( *str));
  127. }
  128. set_label( str, op)
  129. char *str;
  130. struct t_operand *op;
  131. {
  132. char *ptr, *strchr(), *sprint();
  133. static char buf[256];
  134. ptr = strchr( str, '+');
  135. if ( ptr == 0)
  136. op->off = "0";
  137. else {
  138. *ptr = '\0';
  139. op->off = ptr + 1;
  140. }
  141. if ( isdigit( *str) && ( *(str+1) == 'b' || *(str+1) == 'f') &&
  142. *(str+2) == '\0') {
  143. *(str+1) = '\0'; /* remove b or f! */
  144. op->lab = str;
  145. op->type = IS_ILB;
  146. }
  147. else {
  148. op->type = IS_LABEL;
  149. if ( strchr( str, DOLLAR) != 0)
  150. op->lab = str;
  151. else
  152. op->lab = sprint( buf, "\"%s\"", str);
  153. }
  154. }
  155. /******************************************************************************/
  156. mod_RM( reg, op)
  157. int reg;
  158. struct t_operand *op;
  159. {
  160. if ( REG( op))
  161. R233( 0x3, reg, op->reg);
  162. else if ( ADDR( op)) {
  163. R233( 0x0, reg, 0x5);
  164. @reloc4( %$(op->lab), %$(op->off), ABSOLUTE);
  165. }
  166. else if ( strcmp( op->expr, "0") == 0)
  167. switch( op->reg) {
  168. case AX:
  169. case BX:
  170. case CX:
  171. case DX:
  172. case DI:
  173. case SI: R233( 0x0, reg, op->reg);
  174. break;
  175. case BP : R233( 0x1, reg, 0x6); /* Exception! */
  176. @text1( 0);
  177. break;
  178. default : fprint( STDERR, "Wrong index register %d\n",
  179. op->reg);
  180. }
  181. else {
  182. if (isdigit(op->expr[0])) {
  183. long l, atol();
  184. l = atol(op->expr);
  185. if ( l <= 127 && l >= -128) {
  186. switch( op->reg) {
  187. case AX:
  188. case BX:
  189. case CX:
  190. case DX:
  191. case DI:
  192. case BP:
  193. case SI : R233( 0x1, reg, op->reg);
  194. break;
  195. default : fprint( STDERR, "Wrong index register %d\n",
  196. op->reg);
  197. }
  198. @text1( %$(op->expr));
  199. } else {
  200. switch( op->reg) {
  201. case AX:
  202. case BX:
  203. case CX:
  204. case DX:
  205. case DI:
  206. case BP:
  207. case SI : R233( 0x2, reg, op->reg);
  208. break;
  209. default : fprint( STDERR, "Wrong index register %d\n",
  210. op->reg);
  211. }
  212. @text4( %$(op->expr));
  213. }
  214. } else {
  215. @if ( fit_byte( %$(op->expr)))
  216. switch( op->reg) {
  217. case AX:
  218. case BX:
  219. case CX:
  220. case DX:
  221. case DI:
  222. case BP:
  223. case SI : R233( 0x1, reg, op->reg);
  224. break;
  225. default : fprint( STDERR, "Wrong index register %d\n",
  226. op->reg);
  227. }
  228. @text1( %$(op->expr));
  229. @else
  230. switch( op->reg) {
  231. case AX:
  232. case BX:
  233. case CX:
  234. case DX:
  235. case DI:
  236. case BP:
  237. case SI : R233( 0x2, reg, op->reg);
  238. break;
  239. default : fprint( STDERR, "Wrong index register %d\n",
  240. op->reg);
  241. }
  242. @text4( %$(op->expr));
  243. @fi
  244. }
  245. }
  246. }
  247. mv_RG_EADDR( dst, src)
  248. struct t_operand *dst, *src;
  249. {
  250. if ( REG(src) && dst->reg == src->reg)
  251. ; /* Nothing!! result of push/pop optimization */
  252. else {
  253. @text1( 0x8b);
  254. mod_RM( dst->reg, src);
  255. }
  256. }
  257. R233( a, b, c)
  258. int a,b,c;
  259. {
  260. @text1( %d( (a << 6) | ( b << 3) | c));
  261. }
  262. R53( a, b)
  263. int a,b;
  264. {
  265. @text1( %d( (a << 3) | b));
  266. }
  267. small_const(opc, src)
  268. struct t_operand *src;
  269. {
  270. if (isdigit(src->expr[0])) {
  271. long l, atol();
  272. l = atol(src->expr);
  273. if (l >= -128 && l <= 127) {
  274. @text1(%d(opc|02));
  275. @text1(%$(src->expr));
  276. }
  277. else {
  278. @text1(%d(opc));
  279. @text4(%$(src->expr));
  280. }
  281. }
  282. else {
  283. @if (fit_byte(%$(src->expr)))
  284. @text1(%d(opc|02));
  285. @text1(%$(src->expr));
  286. @else
  287. @text1(%d(opc));
  288. @text4(%$(src->expr));
  289. @fi
  290. }
  291. }
  292. small_RMconst(opc, reg, dst, src)
  293. struct t_operand *dst, *src;
  294. {
  295. if (isdigit(src->expr[0])) {
  296. long l, atol();
  297. l = atol(src->expr);
  298. if (l >= -128 && l <= 127) {
  299. @text1(%d(opc|02));
  300. mod_RM(reg, dst);
  301. @text1(%$(src->expr));
  302. }
  303. else {
  304. @text1(%d(opc));
  305. mod_RM(reg, dst);
  306. @text4(%$(src->expr));
  307. }
  308. }
  309. else {
  310. @if (fit_byte(%$(src->expr)))
  311. @text1(%d(opc|02));
  312. mod_RM(reg, dst);
  313. @text1(%$(src->expr));
  314. @else
  315. @text1(%d(opc));
  316. mod_RM(reg, dst);
  317. @text4(%$(src->expr));
  318. @fi
  319. }
  320. }