mach4.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * $Source$
  3. * $State$
  4. */
  5. operation
  6. : OP_BF_BFA CR ',' CR { emit4($1 | ($2<<23) | ($4<<18)); }
  7. | OP_BF_FRA_FRB CR ',' FPR ',' FPR { emit4($1 | ($2<<23) | ($4<<16) | ($6<<11)); }
  8. | OP_BF_L_RA_RB CR ',' u1 ',' GPR ',' GPR { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | ($8<<11)); }
  9. | OP_BF_L_RA_SI CR ',' u1 ',' GPR ',' e16 { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); }
  10. | OP_BF_L_RA_UI CR ',' u1 ',' GPR ',' e16 { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); }
  11. | OP_BF_U_C c CR ',' u4 { emit4($1 | $2 | ($3<<23) | ($5<<12)); }
  12. | OP_BO_BI_BDA u5 ',' u5 ',' bda { emit4($1 | ($2<<21) | ($4<<16) | $6); }
  13. | OP_BO_BI_BDL u5 ',' u5 ',' bdl { emit4($1 | ($2<<21) | ($4<<16) | $6); }
  14. | OP_BO_BI_BH u5 ',' u5 ',' u2 { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  15. | OP_BT_BA_BB u5 ',' u5 ',' u5 { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  16. | OP_BT_C c u5 { emit4($1 | $2 | ($3<<21)); }
  17. | OP_FLM_FRB_C c u8 ',' FPR { emit4($1 | $2 | ($3<<17) | ($5<<11)); }
  18. | OP_FRS_RA_D FPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
  19. | OP_FRS_RA_RB FPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  20. | OP_FRT_FRA_FRB_C c FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
  21. | OP_FRT_FRA_FRC_FRB_C c FPR ',' FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($9<<11) | ($7<<6)); }
  22. | OP_FRT_FRA_FRC_C c FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<6)); }
  23. | OP_FRT_FRB_C c FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<11)); }
  24. | OP_FRT_RA_D FPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
  25. | OP_FRT_RA_RB FPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  26. | OP_FRT_C c FPR { emit4($1 | $2 | ($3<<21)); }
  27. | OP_RT GPR { emit4($1 | ($2<<21)); }
  28. | OP_RT_RA_C c GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16)); }
  29. | OP_RT_RA_D GPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
  30. | OP_RT_RA_DS GPR ',' ds '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
  31. | OP_RT_RA_NB GPR ',' GPR ',' nb { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  32. | OP_RT_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  33. | OP_RT_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
  34. | OP_RT_RA_SI GPR ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
  35. | OP_RT_RA_SI_addic c GPR ',' GPR ',' e16 { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
  36. | OP_RT_SPR GPR ',' SPR { emit4($1 | ($2<<21) | ($4<<11)); }
  37. | OP_RS_FXM u7 ',' GPR { emit4($1 | ($4<<21) | ($2<<12)); }
  38. | OP_RS_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16)); }
  39. | OP_RS_RA_D GPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
  40. | OP_RS_RA_DS GPR ',' ds '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
  41. | OP_RS_RA_NB GPR ',' GPR ',' nb { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  42. | OP_RS_RA_UI GPR ',' GPR ',' e16 { emit4($1 | ($4<<21) | ($2<<16) | $6); }
  43. | OP_RS_RA_UI_CC C GPR ',' GPR ',' e16 { emit4($1 | ($5<<21) | ($3<<16) | $7); }
  44. | OP_RS_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  45. | OP_RS_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
  46. | OP_RS_RA_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
  47. | OP_RS_RA_RB_MB6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
  48. | OP_RS_RA_RB_ME6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
  49. | OP_RS_RA_SH_MB5_ME5_C c GPR ',' GPR ',' u5 ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
  50. | OP_RS_RA_SH_MB6_SH_C c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
  51. | OP_RS_RA_SH_ME6_SH_C c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
  52. | OP_RS_RA_SH5_C c GPR ',' GPR ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
  53. | OP_RS_RA_SH6_C c GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | (($7&0x20)>>4)); }
  54. | OP_RS_SPR SPR ',' GPR { emit4($1 | ($4<<21) | ($2<<11)); }
  55. | OP_TO_RA_RB u5 ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
  56. | OP_TO_RA_SI u5 ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
  57. | OP_LEV u7 { emit4($1 | ($2<<5)); }
  58. | OP_LIA lia { emit4($1 | $2); }
  59. | OP_LIL lil { emit4($1 | $2); }
  60. ;
  61. c
  62. : /* nothing */ { $$ = 0; }
  63. | C { $$ = 1; }
  64. ;
  65. e16
  66. : '<' expr
  67. {
  68. DOTVAL += 2;
  69. newrelo($2.typ, RELOH2 | FIXUPFLAGS);
  70. DOTVAL -= 2;
  71. $$ = ($2.val >> 16) & 0xFFFF;
  72. }
  73. | '>' expr
  74. {
  75. DOTVAL += 2;
  76. newrelo($2.typ, RELO2 | FIXUPFLAGS);
  77. DOTVAL -= 2;
  78. $$ = $2.val & 0xFFFF;
  79. }
  80. | expr
  81. {
  82. DOTVAL += 2;
  83. newrelo($1.typ, RELO2 | FIXUPFLAGS);
  84. DOTVAL -= 2;
  85. $$ = $1.val & 0xFFFF;
  86. }
  87. ;
  88. u8
  89. : absexp
  90. {
  91. if (($1 < 0) || ($1 > 0xFF))
  92. serror("8-bit unsigned value out of range");
  93. $$ = $1;
  94. }
  95. ;
  96. u7
  97. : absexp
  98. {
  99. if (($1 < 0) || ($1 > 0x7F))
  100. serror("7-bit unsigned value out of range");
  101. $$ = $1;
  102. }
  103. ;
  104. u6
  105. : absexp
  106. {
  107. if (($1 < 0) || ($1 > 0x3F))
  108. serror("6-bit unsigned value out of range");
  109. $$ = $1;
  110. }
  111. ;
  112. u5
  113. : absexp
  114. {
  115. if (($1 < 0) || ($1 > 0x1F))
  116. serror("5-bit unsigned value out of range");
  117. $$ = $1;
  118. }
  119. ;
  120. u4
  121. : absexp
  122. {
  123. if (($1 < 0) || ($1 > 0xF))
  124. serror("4-bit unsigned value out of range");
  125. $$ = $1;
  126. }
  127. ;
  128. u1
  129. : absexp
  130. {
  131. if (($1 < 0) || ($1 > 1))
  132. serror("1-bit unsigned value out of range");
  133. $$ = $1;
  134. }
  135. ;
  136. u2
  137. : absexp
  138. {
  139. if (($1 < 0) || ($1 > 0x3))
  140. serror("2-bit unsigned value out of range");
  141. $$ = $1;
  142. }
  143. ;
  144. ds
  145. : e16
  146. {
  147. if ($1 & 3)
  148. serror("value must be 4-aligned");
  149. $$ = $1;
  150. }
  151. ;
  152. nb
  153. : absexp
  154. {
  155. if (($1 < 1) || ($1 > 32))
  156. serror("register count must be in the range 1..32");
  157. if ($1 == 32)
  158. $$ = 0;
  159. else
  160. $$ = $1;
  161. }
  162. ;
  163. bdl
  164. : expr
  165. {
  166. int dist = $1.val - DOTVAL;
  167. fit(fitx(dist, 25));
  168. if (dist & 0x3)
  169. serror("jump targets must be 4-aligned");
  170. DOTVAL += 2;
  171. newrelo($1.typ, RELO2 | RELPC | FIXUPFLAGS);
  172. DOTVAL -= 2;
  173. $$ = dist & 0xFFFD;
  174. }
  175. ;
  176. bda
  177. : expr
  178. {
  179. int target = $1.val;
  180. fit(fitx(target, 16));
  181. if (target & 0x3)
  182. serror("jump targets must be 4-aligned");
  183. DOTVAL += 2;
  184. newrelo($1.typ, RELO2 | FIXUPFLAGS);
  185. DOTVAL -= 2;
  186. $$ = target & 0xFFFD;
  187. }
  188. ;
  189. lil
  190. : expr
  191. {
  192. int dist = $1.val - DOTVAL;
  193. fit(fitx(dist, 26));
  194. if (dist & 0x3)
  195. serror("jump targets must be 4-aligned");
  196. newrelo($1.typ, RELOPPC | RELPC | FIXUPFLAGS);
  197. $$ = dist & 0x03FFFFFD;
  198. }
  199. ;
  200. lia
  201. : expr
  202. {
  203. int target = $1.val;
  204. fit(fitx(target, 26));
  205. if (target & 0x3)
  206. serror("jump targets must be 4-aligned");
  207. newrelo($1.typ, RELOPPC | FIXUPFLAGS);
  208. $$ = target & 0x03FFFFFD;
  209. }
  210. ;