mach4.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. #define RCSID4 "$Id$"
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. *
  6. */
  7. /*
  8. * Zilog Z80 parsing rules
  9. */
  10. operation
  11. : NOOPOP
  12. { emit1($1);}
  13. | LDOP ldargs
  14. | PSHPOP R16
  15. { switch ($2) {
  16. case BC: emit1($1); break;
  17. case DE: emit1($1 | 020); break;
  18. case AF: emit1($1 | 060); break;
  19. case HL:
  20. case IX:
  21. case IY: xyreg($2,$1 | 040); break;
  22. default: serror("register error");
  23. }
  24. }
  25. | EXOP R16 ',' R16
  26. { if ($2==DE && $4==HL)
  27. emit1(0353);
  28. else if ($2==AF && $4==AF2)
  29. emit1(010);
  30. else serror("register error");
  31. }
  32. | EXOP '(' R16 ')' ',' R16
  33. { if ($3!=SP) serror("register error");
  34. xyreg($6,$1);
  35. }
  36. | E_ED
  37. { emit1(0355); emit1($1);}
  38. | ADDOP R16 ',' R16
  39. { if ($4 == $2)
  40. xyreg($2,051);
  41. else {
  42. if ($4==HL || $4>SP)
  43. serror("register error");
  44. xyreg($2,011 | $4<<4);
  45. }
  46. }
  47. | ADCSBC R16 ',' R16
  48. { if ($2!=HL || $4>SP) serror("register error");
  49. emit1(0355);
  50. emit1(($1==0210 ? 0112 : 0102) | ($4<<4));
  51. }
  52. | INCDEC R16
  53. { switch ($2) {
  54. case BC: case DE: case SP:
  55. emit1(($1==04 ? 03 : 013) | $2<<4);
  56. break;
  57. case HL: case IX: case IY:
  58. xyreg($2,$1==04 ? 043 : 053);
  59. break;
  60. default: serror("register error");
  61. }
  62. }
  63. | INCDEC r8
  64. { emit1($1 | $2<<3);}
  65. | INCDEC ind
  66. { xymem($2,$1 | 060);}
  67. | ari8 r8
  68. { emit1($1 | $2);}
  69. | ari8 expr
  70. { emit1($1 | 0106); emit1($2.val);}
  71. | ari8 ind
  72. { xymem($2,$1 | 06);}
  73. | IMOP absexp
  74. { emit1(0355);
  75. switch ($2) {
  76. case 0: emit1(0106); break;
  77. case 1: emit1(0126); break;
  78. case 2: emit1(0136); break;
  79. default: serror("range 0..2");
  80. }
  81. }
  82. | ROTATE r8
  83. { emit1(0313); emit1($1 | $2);}
  84. | ROTATE ind
  85. { xymem($2,0313); emit1($1 | 06);}
  86. | BITS absexp ',' r8
  87. { fit(fit3($2));
  88. emit1(0313); emit1($1 | low3($2)<<3 | $4);
  89. }
  90. | BITS absexp ',' ind
  91. { fit(fit3($2));
  92. xymem($4,0313);
  93. emit1($1 | low3($2)<<3 | 06);
  94. }
  95. | JP expr
  96. { emit1($1);
  97. #ifdef RELOCATION
  98. newrelo($2.typ, RELO2);
  99. #endif
  100. emit2($2.val);
  101. }
  102. | JP coco ',' expr
  103. { emit1(0302 | $2<<3);
  104. #ifdef RELOCATION
  105. newrelo($4.typ, RELO2);
  106. #endif
  107. emit2($4.val);
  108. }
  109. | JP indir
  110. { xyreg($2,0351);}
  111. | JR expr
  112. { branch($1,$2);}
  113. | JR coco ',' expr
  114. { if ($2 > 3) serror("bad condition code");
  115. branch(040 | ($2<<3), $4);
  116. }
  117. | DJNZ expr
  118. { branch($1,$2);}
  119. | CALL expr
  120. { emit1($1);
  121. #ifdef RELOCATION
  122. newrelo($2.typ, RELO2);
  123. #endif
  124. emit2($2.val);
  125. }
  126. | CALL coco ',' expr
  127. { emit1(0304 | $2<<3);
  128. #ifdef RELOCATION
  129. newrelo($4.typ, RELO2);
  130. #endif
  131. emit2($4.val);
  132. }
  133. | RET
  134. { emit1($1);}
  135. | RET coco
  136. { emit1(0300 | $2<<3);}
  137. | RST absexp
  138. { if (($2&070)!=$2)
  139. serror("rst expression out of range");
  140. emit1($1 | $2);
  141. }
  142. | IN R8 ',' expr
  143. { if ($2 != A) serror("register error");
  144. emit1($1);
  145. #ifdef RELOCATION
  146. newrelo($4.typ, RELO1);
  147. #endif
  148. emit1($4.val);
  149. }
  150. | IN R8 ',' R8
  151. { if ($4 != C) serror("register error");
  152. emit1(0355); emit1(0100 | $2<<3);
  153. }
  154. | OUT expr ',' R8
  155. { if ($4 != A) serror("register error");
  156. emit1($1);
  157. #ifdef RELOCATION
  158. newrelo($2.typ, RELO1);
  159. #endif
  160. emit1($2.val);
  161. }
  162. | OUT R8 ',' R8
  163. { if ($2 != C) serror("register error");
  164. emit1(0355); emit1(0101 | $4<<3);
  165. }
  166. ;
  167. ari8 : ARI8
  168. | ADDOP R8 ','
  169. { if ($2 != A) serror("register error");}
  170. | ADCSBC R8 ','
  171. { if ($2 != A) serror("register error");}
  172. ;
  173. ldargs : R8 ',' R8
  174. { if ($1==F || $3==F) serror("register error");
  175. if ($1<=A && $3<=A)
  176. emit1(0100 | $1<<3 | $3);
  177. else {
  178. emit1(0355);
  179. if ((($1==A) ^ ($3==A)) == 0)
  180. serror("register error");
  181. emit1( 0107 |
  182. ($1==R||$3==R)<<3 |
  183. ($1==A)<<4
  184. );
  185. }
  186. }
  187. | R8 ',' expr
  188. { if ($1==F || $1==I || $1==R)
  189. serror("register error");
  190. emit1(06 | $1<<3);
  191. #ifdef RELOCATION
  192. newrelo($3.typ, RELO1);
  193. #endif
  194. emit1($3.val);
  195. }
  196. | R8 ',' indir
  197. { if ($1==F || $1==I || $1==R)
  198. serror("register error");
  199. if ($1==A && ($3==BC || $3==DE))
  200. emit1($3==BC ? 012 : 032);
  201. else
  202. xymem($3,0106 | $1<<3);
  203. }
  204. | R8 ',' index
  205. { if ($1==F || $1==I || $1==R)
  206. serror("register error");
  207. xymem($3,0106 | $1<<3);
  208. }
  209. | R8 ',' '(' expr ')'
  210. { if ($1!=A) serror("register error");
  211. emit1(072);
  212. #ifdef RELOCATION
  213. newrelo($4.typ, RELO2);
  214. #endif
  215. emit2($4.val);
  216. }
  217. | indir ',' r8
  218. { if ($3==A && ($1==BC || $1==DE))
  219. emit1($1==BC ? 02 : 022);
  220. else
  221. xymem($1,0160 | $3);
  222. }
  223. | index ',' r8
  224. { xymem($1,0160 | $3);}
  225. | indir ',' expr
  226. { xymem($1,066);
  227. #ifdef RELOCATION
  228. newrelo($3.typ, RELO1);
  229. #endif
  230. emit1($3.val);
  231. }
  232. | index ',' expr
  233. { xymem($1,066);
  234. #ifdef RELOCATION
  235. newrelo($3.typ, RELO1);
  236. #endif
  237. emit1($3.val);
  238. }
  239. | R16 ',' expr
  240. { switch ($1) {
  241. case BC: case DE: case HL: case SP:
  242. emit1(01 | $1<<4); break;
  243. case IX: case IY:
  244. xyreg($1,041); break;
  245. default: serror("register error");
  246. }
  247. #ifdef RELOCATION
  248. newrelo($3.typ, RELO2);
  249. #endif
  250. emit2($3.val);
  251. }
  252. | R16 ',' R16
  253. { if ($1!=SP) serror("register error");
  254. xyreg($3,0371);
  255. }
  256. | R16 ',' '(' expr ')'
  257. { switch ($1) {
  258. case BC: case DE: case SP:
  259. emit1(0355); emit1(0113 | $1<<4); break;
  260. case HL: case IX: case IY:
  261. xyreg($1,052); break;
  262. default: serror("register error");
  263. }
  264. #ifdef RELOCATION
  265. newrelo($4.typ, RELO2);
  266. #endif
  267. emit2($4.val);
  268. }
  269. | '(' expr ')' ',' R8
  270. { if ($5!=A) serror("register error");
  271. emit1(062);
  272. #ifdef RELOCATION
  273. newrelo($2.typ, RELO2);
  274. #endif
  275. emit2($2.val);
  276. }
  277. | '(' expr ')' ',' R16
  278. { switch ($5) {
  279. case BC: case DE: case SP:
  280. emit1(0355); emit1(0103 | $5<<4); break;
  281. case HL: case IX: case IY:
  282. xyreg($5,042); break;
  283. default: serror("register error");
  284. }
  285. #ifdef RELOCATION
  286. newrelo($2.typ, RELO2);
  287. #endif
  288. emit2($2.val);
  289. }
  290. ;
  291. r8 : R8
  292. { if ($1==F || $1==I || $1==R)
  293. serror("register error");
  294. }
  295. ;
  296. indir : '(' R16 ')'
  297. { if ($2>=SP && $2!=IX && $2!=IY)
  298. serror("register error");
  299. exp_ind.typ = S_ABS; exp_ind.val = 0;
  300. $$ = $2;
  301. }
  302. ;
  303. index : '(' R16 '+' expr ')'
  304. { if ($2!=IX && $2!=IY) serror("register error");
  305. exp_ind = $4;
  306. RELOMOVE(rel_ind, relonami);
  307. $$ = $2;
  308. }
  309. | '(' R16 '-' expr ')'
  310. {
  311. if ($2!=IX && $2!=IY) serror("register error");
  312. fit(fitb($4.val));
  313. exp_ind = $4;
  314. RELOMOVE(rel_ind, relonami);
  315. $$ = $2;
  316. }
  317. ;
  318. ind : indir
  319. | index
  320. ;
  321. coco : CC
  322. | R8
  323. { if ($1 != C) serror("bad condition code");
  324. $$ = 3;
  325. }
  326. ;