as.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #include <ctype.h>
  2. #include "as.h"
  3. #define DOLLAR '$'
  4. #define LEFT '('
  5. #define RIGHT ')'
  6. /*****************************************************************************/
  7. /* Een constraint-function */
  8. cst( arg)
  9. struct t_operand *arg;
  10. {
  11. return( arg->type == CONST);
  12. }
  13. /*****************************************************************************/
  14. /* decode_operand() recognizes the follwing assembly-argumnets:
  15. $cst : CONST
  16. register : REGISTER
  17. -(register) : AUTO_DEC
  18. (register)+ : AUTO_INC
  19. (register) : REG_DEF
  20. indx(register) : IND_REG
  21. label+offset : LABEL
  22. label[b|f] : L_ILB
  23. */
  24. /* An assembly instruction has at most 5 arguments.
  25. * This is for the time being.
  26. */
  27. char lab_buf[4][256],
  28. ind_buf[4][256],
  29. *match(), *lab(), *ind(), *end_arg(), *strchr();
  30. static int n_index = -1;
  31. process_label( l)
  32. char *l;
  33. {
  34. }
  35. process_mnemonic( m)
  36. char *m;
  37. {
  38. }
  39. process_operand( arg, op)
  40. register char *arg;
  41. register struct t_operand *op;
  42. {
  43. register char *einde;
  44. if ( n_index == 3)
  45. n_index = 0;
  46. else
  47. n_index++;
  48. if ( arg[0] == '~' ) {
  49. op->type = CONST;
  50. op->cst = arg+1;
  51. }
  52. else if ( is_reg( arg, &(op->num)) ) {
  53. op->type = REGISTER;
  54. }
  55. else if ((arg[0]=='-') && (arg[1] == LEFT) &&
  56. is_reg( arg+2,&(op->num))) {
  57. op->type = AUTO_DEC;
  58. }
  59. else if( ( arg[0] == LEFT) && is_reg( arg+1, &(op->num))) {
  60. arg = match( arg, RIGHT);
  61. if ( *(arg+1) == '+')
  62. op->type = AUTO_INC;
  63. else
  64. op->type = REG_DEF;
  65. }
  66. else {
  67. einde = end_arg( arg);
  68. if ( (*einde == 'b' || *einde == 'f') && isdigit( *(einde-1))) {
  69. *einde = '\0';
  70. op->type = L_ILB;
  71. op->offset = "0";
  72. op->lab = arg;
  73. }
  74. else if ( *einde == RIGHT) {
  75. op->type = IND_REG;
  76. arg = ind( ind_buf[ n_index], arg);
  77. if ( is_reg( arg+1, &(op->num)))
  78. op->indx = ind_buf[ n_index];
  79. else
  80. fprint( STDERR, "unknown argtype %s\n", arg);
  81. }
  82. else {
  83. op->type = LABEL;
  84. arg = lab( lab_buf[ n_index], arg);
  85. op->lab = lab_buf[ n_index];
  86. if ( *arg == '\0')
  87. op->offset = "0";
  88. else
  89. op->offset = arg+1;
  90. }
  91. }
  92. }
  93. char *ind( buf, str)
  94. register char *buf, *str;
  95. /* Reads the index in front of '(register)'.
  96. */
  97. {
  98. while ( *str != LEFT)
  99. *buf++ = *str++;
  100. *buf = '\0';
  101. return( str);
  102. }
  103. char *lab( buf, str)
  104. register char *buf, *str;
  105. /* Reads 'label' in front of '+offset'.
  106. */
  107. {
  108. while ( ( *str != '+') && ( *str != '\0'))
  109. *buf++ = *str++;
  110. *buf = '\0';
  111. while ( isspace( *(buf-1)) ) {
  112. *(buf-1) = '\0';
  113. buf--;
  114. }
  115. return( str);
  116. }
  117. int is_reg( str, num)
  118. register char *str;
  119. register int *num;
  120. /* Is "str" a 'registers' ?
  121. */
  122. {
  123. if ( ( *str == 'a') && ( *(str+1) == 'p')) {
  124. *num = 12;
  125. return( TRUE);
  126. }
  127. else if ( ( *str == 'f') && ( *(str+1) == 'p')) {
  128. *num = 13;
  129. return( TRUE);
  130. }
  131. else if ( ( *str == 's') && ( *(str+1) == 'p')) {
  132. *num = 14;
  133. return( TRUE);
  134. }
  135. if ( *str == 'r') {
  136. if ( isdigit( *(str+1)) && isdigit( *(str+2))) {
  137. *num = ( *(str+1) - '0') * 10 + *(str+2) - '0';
  138. return( TRUE);
  139. }
  140. else if ( isdigit( *(str+1))) {
  141. *num = *(str+1) - '0';
  142. return( TRUE);
  143. }
  144. else
  145. return( FALSE);
  146. }
  147. return( FALSE);
  148. }
  149. char *end_arg( str)
  150. register char *str;
  151. /* Shift to the last character of "str".
  152. */
  153. {
  154. while ( *str != '\0')
  155. str++;
  156. return( str-1);
  157. }
  158. char *match( str, sym)
  159. register char *str;
  160. char sym;
  161. {
  162. while ( *str != sym)
  163. str++;
  164. return( str);
  165. }
  166. /******************************************************************************/
  167. char my_buf[256];
  168. gen_operand( op)
  169. register struct t_operand *op;
  170. /* Generate object-code for a argument.
  171. */
  172. {
  173. switch( op->type) {
  174. case CONST :
  175. if (isdigit(op->cst[0])) {
  176. long l, atol();
  177. l = atol(op->cst);
  178. if (fit_6bits(l)) {
  179. @text1(%$(op->cst));
  180. }
  181. else {
  182. @text1( 0x8f);
  183. @text4( %$(op->cst));
  184. }
  185. }
  186. else {
  187. @__as_const(%$(op->cst));
  188. }
  189. break;
  190. case REGISTER: @text1( %d(0x50 | op->num));
  191. break;
  192. case REG_DEF : @text1( %d(0x60 | op->num));
  193. break;
  194. case AUTO_DEC : @text1( %d(0x70 | op->num));
  195. break;
  196. case AUTO_INC : @text1( %d(0x80 | op->num));
  197. break;
  198. case IND_REG :
  199. if (isdigit(op->indx[0])) {
  200. long l, atol();
  201. l = atol(op->indx);
  202. if (fit_byte(l)) {
  203. @text1( %d(0xa0 | op->num));
  204. @text1( %$(op->indx));
  205. } else if (fit_word(l)) {
  206. @text1( %d(0xc0 | op->num));
  207. @text2( %$(op->indx));
  208. } else {
  209. @text1( %d(0xe0 | op->num));
  210. @text4( %$(op->indx));
  211. }
  212. }
  213. else {
  214. @__as_indexed(%$(op->indx) , %d(op->num));
  215. }
  216. break;
  217. case LABEL : @text1( 0xef);
  218. if ( strchr( op->lab, DOLLAR)) {
  219. @reloc4( %$(op->lab), %$(op->offset), PC_REL);
  220. }
  221. else if ( strchr( op->lab, LEFT)) {
  222. @reloc4( %$(op->lab), %$(op->offset), PC_REL);
  223. }
  224. else {
  225. sprint( my_buf, "\"%s\"", op->lab);
  226. @reloc4( %$(my_buf), %$(op->offset) , PC_REL);
  227. }
  228. break;
  229. case L_ILB : @text1( %dist( op->lab));
  230. break;
  231. default : fprint( STDERR, "error");
  232. }
  233. }