as.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. #include "arg_type.h"
  2. #include "as.h"
  3. static struct t_operand dummy = { IS_REG, AX, 0, 0, 0};
  4. struct t_operand saved_op, *AX_oper = &dummy;
  5. save_op( op)
  6. struct t_operand *op;
  7. {
  8. saved_op.type = op->type;
  9. saved_op.reg = op->reg;
  10. saved_op.expr = op->expr;
  11. saved_op.lab = op->lab;
  12. saved_op.off = op->off;
  13. }
  14. #define last( s) ( s + strlen( s) - 1)
  15. #define LEFT '('
  16. #define RIGHT ')'
  17. #define DOLLAR '$'
  18. block_assemble( instr, nr, first, Last)
  19. char **instr;
  20. int nr, first, Last;
  21. {
  22. int i;
  23. if ( first) {
  24. if( strncmp( instr[0], "pop", 3) == 0) {
  25. *instr[0] = 'P';
  26. *( instr[0]+1) = 'O';
  27. *( instr[0]+2) = 'P';
  28. }
  29. else
  30. @clean_push_buf();
  31. }
  32. if ( Last && strncmp( instr[nr-1], "push", 4) == 0) {
  33. *instr[nr-1] = 'P';
  34. *( instr[nr-1]+1) = 'U';
  35. *( instr[nr-1]+2) = 'S';
  36. *( instr[nr-1]+3) = 'H';
  37. }
  38. for( i=0; i<nr; i++)
  39. assemble( instr[i]);
  40. }
  41. process_label( l)
  42. char *l;
  43. {
  44. }
  45. process_mnemonic( m)
  46. char *m;
  47. {
  48. }
  49. process_operand( str, op)
  50. char *str;
  51. struct t_operand *op;
  52. /* expr -> IS_DATA en IS_LABEL
  53. * reg -> IS_REG en IS_ACCU
  54. * (expr) -> IS_ADDR
  55. * expr(reg) -> IS_MEM
  56. */
  57. {
  58. char *ptr, *strchr();
  59. op->type = UNKNOWN;
  60. if ( *last( str) == RIGHT) {
  61. ptr = strchr( str, LEFT);
  62. *last( str) = '\0';
  63. *ptr = '\0';
  64. if ( is_reg( ptr+1, op)) {
  65. op->type = IS_MEM;
  66. op->expr = ( *str == '\0' ? "0" : str);
  67. }
  68. else {
  69. set_label( ptr+1, op);
  70. op->type = IS_ADDR;
  71. }
  72. }
  73. else
  74. if ( is_reg( str, op))
  75. op->type = IS_REG;
  76. else {
  77. if ( contains_label( str))
  78. set_label( str, op);
  79. else {
  80. op->type = IS_DATA;
  81. op->expr = str;
  82. }
  83. }
  84. }
  85. int is_reg( str, op)
  86. char *str;
  87. struct t_operand *op;
  88. {
  89. if ( strlen( str) != 2)
  90. return( 0);
  91. switch ( *(str+1)) {
  92. case 'x' :
  93. case 'l' : switch( *str) {
  94. case 'a' : op->reg = 0;
  95. return( TRUE);
  96. case 'c' : op->reg = 1;
  97. return( TRUE);
  98. case 'd' : op->reg = 2;
  99. return( TRUE);
  100. case 'b' : op->reg = 3;
  101. return( TRUE);
  102. default : return( FALSE);
  103. }
  104. case 'h' : switch( *str) {
  105. case 'a' : op->reg = 4;
  106. return( TRUE);
  107. case 'c' : op->reg = 5;
  108. return( TRUE);
  109. case 'd' : op->reg = 6;
  110. return( TRUE);
  111. case 'b' : op->reg = 7;
  112. return( TRUE);
  113. default : return( FALSE);
  114. }
  115. case 'p' : switch ( *str) {
  116. case 's' : op->reg = 4;
  117. return( TRUE);
  118. case 'b' : op->reg = 5;
  119. return( TRUE);
  120. default : return( FALSE);
  121. }
  122. case 'i' : switch ( *str) {
  123. case 's' : op->reg = 6;
  124. return( TRUE);
  125. case 'd' : op->reg = 7;
  126. return( TRUE);
  127. default : return( FALSE);
  128. }
  129. default : return( FALSE);
  130. }
  131. }
  132. #include <ctype.h>
  133. #define isletter( c) ( isalpha( c) || c == '_')
  134. int contains_label( str)
  135. char *str;
  136. {
  137. while( !isletter( *str) && *str != '\0')
  138. if ( *str == '$')
  139. if ( arg_type( str) == STRING)
  140. return( TRUE);
  141. else
  142. str += 2;
  143. else
  144. str++;
  145. return( isletter( *str));
  146. }
  147. set_label( str, op)
  148. char *str;
  149. struct t_operand *op;
  150. {
  151. char *ptr, *strchr(), *sprint();
  152. static char buf[256];
  153. ptr = strchr( str, '+');
  154. if ( ptr == 0)
  155. op->off = "0";
  156. else {
  157. *ptr = '\0';
  158. op->off = ptr + 1;
  159. }
  160. if ( isdigit( *str) && ( *(str+1) == 'b' || *(str+1) == 'f') &&
  161. *(str+2) == '\0') {
  162. *(str+1) = '\0'; /* b of f verwijderen! */
  163. op->lab = str;
  164. op->type = IS_ILB;
  165. }
  166. else {
  167. op->type = IS_LABEL;
  168. if ( strchr( str, DOLLAR) != 0)
  169. op->lab = str;
  170. else
  171. /* nood oplossing */
  172. op->lab = sprint( buf, "\"%s\"", str);
  173. }
  174. }
  175. /******************************************************************************/
  176. mod_RM( reg, op)
  177. int reg;
  178. struct t_operand *op;
  179. {
  180. if ( REG( op))
  181. R233( 0x3, reg, op->reg);
  182. else if ( ADDR( op)) {
  183. R233( 0x0, reg, 0x6);
  184. @reloc2( %$(op->lab), %$(op->off), ABSOLUTE);
  185. }
  186. else if ( strcmp( op->expr, "0") == 0)
  187. switch( op->reg) {
  188. case SI : R233( 0x0, reg, 0x4);
  189. break;
  190. case DI : R233( 0x0, reg, 0x5);
  191. break;
  192. case BP : R233( 0x1, reg, 0x6); /* Uitzondering! */
  193. @text1( 0);
  194. break;
  195. case BX : R233( 0x0, reg, 0x7);
  196. break;
  197. default : fprint( STDERR, "Wrong index register %d\n",
  198. op->reg);
  199. }
  200. else {
  201. @if ( fit_byte( %$(op->expr)))
  202. switch( op->reg) {
  203. case SI : R233( 0x1, reg, 0x4);
  204. break;
  205. case DI : R233( 0x1, reg, 0x5);
  206. break;
  207. case BP : R233( 0x1, reg, 0x6);
  208. break;
  209. case BX : R233( 0x1, reg, 0x7);
  210. break;
  211. default : fprint( STDERR, "Wrong index register %d\n",
  212. op->reg);
  213. }
  214. @text1( %$(op->expr));
  215. @else
  216. switch( op->reg) {
  217. case SI : R233( 0x2, reg, 0x4);
  218. break;
  219. case DI : R233( 0x2, reg, 0x5);
  220. break;
  221. case BP : R233( 0x2, reg, 0x6);
  222. break;
  223. case BX : R233( 0x2, reg, 0x7);
  224. break;
  225. default : fprint( STDERR, "Wrong index register %d\n",
  226. op->reg);
  227. }
  228. @text2( %$(op->expr));
  229. @fi
  230. }
  231. }
  232. mov_REG_EADDR( dst, src)
  233. struct t_operand *dst, *src;
  234. {
  235. if ( REG(src) && dst->reg == src->reg)
  236. ; /* Nothing!! result of push/pop optimization */
  237. else {
  238. @text1( 0x8b);
  239. mod_RM( dst->reg, src);
  240. }
  241. }
  242. R233( a, b, c)
  243. int a,b,c;
  244. {
  245. @text1( %d( (a << 6) | ( b << 3) | c));
  246. }
  247. R53( a, b)
  248. int a,b;
  249. {
  250. @text1( %d( (a << 3) | b));
  251. }