rl78-parse.y 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601
  1. /* rl78-parse.y Renesas RL78 parser
  2. Copyright (C) 2011-2015 Free Software Foundation, Inc.
  3. This file is part of GAS, the GNU Assembler.
  4. GAS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3, or (at your option)
  7. any later version.
  8. GAS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GAS; see the file COPYING. If not, write to the Free
  14. Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
  15. 02110-1301, USA. */
  16. %{
  17. #include "as.h"
  18. #include "safe-ctype.h"
  19. #include "rl78-defs.h"
  20. static int rl78_lex (void);
  21. /* Ok, here are the rules for using these macros...
  22. B*() is used to specify the base opcode bytes. Fields to be filled
  23. in later, leave zero. Call this first.
  24. F() and FE() are used to fill in fields within the base opcode bytes. You MUST
  25. call B*() before any F() or FE().
  26. [UN]*O*(), PC*() appends operands to the end of the opcode. You
  27. must call P() and B*() before any of these, so that the fixups
  28. have the right byte location.
  29. O = signed, UO = unsigned, NO = negated, PC = pcrel
  30. IMM() adds an immediate and fills in the field for it.
  31. NIMM() same, but negates the immediate.
  32. NBIMM() same, but negates the immediate, for sbb.
  33. DSP() adds a displacement, and fills in the field for it.
  34. Note that order is significant for the O, IMM, and DSP macros, as
  35. they append their data to the operand buffer in the order that you
  36. call them.
  37. Use "disp" for displacements whenever possible; this handles the
  38. "0" case properly. */
  39. #define B1(b1) rl78_base1 (b1)
  40. #define B2(b1, b2) rl78_base2 (b1, b2)
  41. #define B3(b1, b2, b3) rl78_base3 (b1, b2, b3)
  42. #define B4(b1, b2, b3, b4) rl78_base4 (b1, b2, b3, b4)
  43. /* POS is bits from the MSB of the first byte to the LSB of the last byte. */
  44. #define F(val,pos,sz) rl78_field (val, pos, sz)
  45. #define FE(exp,pos,sz) rl78_field (exp_val (exp), pos, sz);
  46. #define O1(v) rl78_op (v, 1, RL78REL_DATA)
  47. #define O2(v) rl78_op (v, 2, RL78REL_DATA)
  48. #define O3(v) rl78_op (v, 3, RL78REL_DATA)
  49. #define O4(v) rl78_op (v, 4, RL78REL_DATA)
  50. #define PC1(v) rl78_op (v, 1, RL78REL_PCREL)
  51. #define PC2(v) rl78_op (v, 2, RL78REL_PCREL)
  52. #define PC3(v) rl78_op (v, 3, RL78REL_PCREL)
  53. #define IMM(v,pos) F (immediate (v, RL78REL_SIGNED, pos), pos, 2); \
  54. if (v.X_op != O_constant && v.X_op != O_big) rl78_linkrelax_imm (pos)
  55. #define NIMM(v,pos) F (immediate (v, RL78REL_NEGATIVE, pos), pos, 2)
  56. #define NBIMM(v,pos) F (immediate (v, RL78REL_NEGATIVE_BORROW, pos), pos, 2)
  57. #define DSP(v,pos,msz) if (!v.X_md) rl78_relax (RL78_RELAX_DISP, pos); \
  58. else rl78_linkrelax_dsp (pos); \
  59. F (displacement (v, msz), pos, 2)
  60. #define id24(a,b2,b3) B3 (0xfb+a, b2, b3)
  61. static int expr_is_sfr (expressionS);
  62. static int expr_is_saddr (expressionS);
  63. static int expr_is_word_aligned (expressionS);
  64. static int exp_val (expressionS exp);
  65. static int need_flag = 0;
  66. static int rl78_in_brackets = 0;
  67. static int rl78_last_token = 0;
  68. static char * rl78_init_start;
  69. static char * rl78_last_exp_start = 0;
  70. static int rl78_bit_insn = 0;
  71. #define YYDEBUG 1
  72. #define YYERROR_VERBOSE 1
  73. #define NOT_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFF1F")
  74. #define SA(e) if (!expr_is_saddr (e)) NOT_SADDR;
  75. #define SET_SA(e) e.X_md = BFD_RELOC_RL78_SADDR
  76. #define NOT_SFR rl78_error ("Expression not 0xFFF00 to 0xFFFFF")
  77. #define SFR(e) if (!expr_is_sfr (e)) NOT_SFR;
  78. #define NOT_SFR_OR_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFFFF")
  79. #define NOT_ES if (rl78_has_prefix()) rl78_error ("ES: prefix not allowed here");
  80. #define WA(x) if (!expr_is_word_aligned (x)) rl78_error ("Expression not word-aligned");
  81. #define ISA_G10(s) if (!rl78_isa_g10()) rl78_error (s " is only supported on the G10")
  82. #define ISA_G13(s) if (!rl78_isa_g13()) rl78_error (s " is only supported on the G13")
  83. #define ISA_G14(s) if (!rl78_isa_g14()) rl78_error (s " is only supported on the G14")
  84. static void check_expr_is_bit_index (expressionS);
  85. #define Bit(e) check_expr_is_bit_index (e);
  86. /* Returns TRUE (non-zero) if the expression is a constant in the
  87. given range. */
  88. static int check_expr_is_const (expressionS, int vmin, int vmax);
  89. /* Convert a "regb" value to a "reg_xbc" value. Error if other
  90. registers are passed. Needed to avoid reduce-reduce conflicts. */
  91. static int
  92. reg_xbc (int reg)
  93. {
  94. switch (reg)
  95. {
  96. case 0: /* X */
  97. return 0x10;
  98. case 3: /* B */
  99. return 0x20;
  100. case 2: /* C */
  101. return 0x30;
  102. default:
  103. rl78_error ("Only X, B, or C allowed here");
  104. return 0;
  105. }
  106. }
  107. %}
  108. %name-prefix="rl78_"
  109. %union {
  110. int regno;
  111. expressionS exp;
  112. }
  113. %type <regno> regb regb_na regw regw_na FLAG sfr
  114. %type <regno> A X B C D E H L AX BC DE HL
  115. %type <exp> EXPR
  116. %type <regno> addsub addsubw andor1 bt_bf setclr1 oneclrb oneclrw
  117. %type <regno> incdec incdecw
  118. %token A X B C D E H L AX BC DE HL
  119. %token SPL SPH PSW CS ES PMC MEM
  120. %token FLAG SP CY
  121. %token RB0 RB1 RB2 RB3
  122. %token EXPR UNKNOWN_OPCODE IS_OPCODE
  123. %token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW
  124. %token ADD ADDC ADDW AND_ AND1
  125. /* BC is also a register pair */
  126. %token BF BH BNC BNH BNZ BR BRK BRK1 BT BTCLR BZ
  127. %token CALL CALLT CLR1 CLRB CLRW CMP CMP0 CMPS CMPW
  128. %token DEC DECW DI DIVHU DIVWU
  129. %token EI
  130. %token HALT
  131. %token INC INCW
  132. %token MACH MACHU MOV MOV1 MOVS MOVW MULH MULHU MULU
  133. %token NOP NOT1
  134. %token ONEB ONEW OR OR1
  135. %token POP PUSH
  136. %token RET RETI RETB ROL ROLC ROLWC ROR RORC
  137. %token SAR SARW SEL SET1 SHL SHLW SHR SHRW
  138. %token SKC SKH SKNC SKNH SKNZ SKZ STOP SUB SUBC SUBW
  139. %token XCH XCHW XOR XOR1
  140. %%
  141. /* ====================================================================== */
  142. statement :
  143. UNKNOWN_OPCODE
  144. { as_bad (_("Unknown opcode: %s"), rl78_init_start); }
  145. /* The opcodes are listed in approximately alphabetical order. */
  146. /* For reference:
  147. sfr = special function register - symbol, 0xFFF00 to 0xFFFFF
  148. sfrp = special function register - symbol, 0xFFF00 to 0xFFFFE, even only
  149. saddr = 0xFFE20 to 0xFFF1F
  150. saddrp = 0xFFE20 to 0xFFF1E, even only
  151. addr20 = 0x00000 to 0xFFFFF
  152. addr16 = 0x00000 to 0x0FFFF, even only for 16-bit ops
  153. addr5 = 0x00000 to 0x000BE, even only
  154. */
  155. /* ---------------------------------------------------------------------- */
  156. /* addsub is ADD, ADDC, SUB, SUBC, AND, OR, XOR, and parts of CMP. */
  157. | addsub A ',' '#' EXPR
  158. { B1 (0x0c|$1); O1 ($5); }
  159. | addsub EXPR {SA($2)} ',' '#' EXPR
  160. { B1 (0x0a|$1); SET_SA ($2); O1 ($2); O1 ($6); }
  161. | addsub A ',' A
  162. { B2 (0x61, 0x01|$1); }
  163. | addsub A ',' regb_na
  164. { B2 (0x61, 0x08|$1); F ($4, 13, 3); }
  165. | addsub regb_na ',' A
  166. { B2 (0x61, 0x00|$1); F ($2, 13, 3); }
  167. | addsub A ',' EXPR {SA($4)}
  168. { B1 (0x0b|$1); SET_SA ($4); O1 ($4); }
  169. | addsub A ',' opt_es '!' EXPR
  170. { B1 (0x0f|$1); O2 ($6); rl78_linkrelax_addr16 (); }
  171. | addsub A ',' opt_es '[' HL ']'
  172. { B1 (0x0d|$1); }
  173. | addsub A ',' opt_es '[' HL '+' EXPR ']'
  174. { B1 (0x0e|$1); O1 ($8); }
  175. | addsub A ',' opt_es '[' HL '+' B ']'
  176. { B2 (0x61, 0x80|$1); }
  177. | addsub A ',' opt_es '[' HL '+' C ']'
  178. { B2 (0x61, 0x82|$1); }
  179. | addsub opt_es '!' EXPR ',' '#' EXPR
  180. { if ($1 != 0x40)
  181. { rl78_error ("Only CMP takes these operands"); }
  182. else
  183. { B1 (0x00|$1); O2 ($4); O1 ($7); rl78_linkrelax_addr16 (); }
  184. }
  185. /* ---------------------------------------------------------------------- */
  186. | addsubw AX ',' '#' EXPR
  187. { B1 (0x04|$1); O2 ($5); }
  188. | addsubw AX ',' regw
  189. { B1 (0x01|$1); F ($4, 5, 2); }
  190. | addsubw AX ',' EXPR {SA($4)}
  191. { B1 (0x06|$1); SET_SA ($4); O1 ($4); }
  192. | addsubw AX ',' opt_es '!' EXPR
  193. { B1 (0x02|$1); O2 ($6); rl78_linkrelax_addr16 (); }
  194. | addsubw AX ',' opt_es '[' HL '+' EXPR ']'
  195. { B2 (0x61, 0x09|$1); O1 ($8); }
  196. | addsubw AX ',' opt_es '[' HL ']'
  197. { B3 (0x61, 0x09|$1, 0); }
  198. | addsubw SP ',' '#' EXPR
  199. { B1 ($1 ? 0x20 : 0x10); O1 ($5);
  200. if ($1 == 0x40)
  201. rl78_error ("CMPW SP,#imm not allowed");
  202. }
  203. /* ---------------------------------------------------------------------- */
  204. | andor1 CY ',' sfr '.' EXPR {Bit($6)}
  205. { B3 (0x71, 0x08|$1, $4); FE ($6, 9, 3); }
  206. | andor1 CY ',' EXPR '.' EXPR {Bit($6)}
  207. { if (expr_is_sfr ($4))
  208. { B2 (0x71, 0x08|$1); FE ($6, 9, 3); O1 ($4); }
  209. else if (expr_is_saddr ($4))
  210. { B2 (0x71, 0x00|$1); FE ($6, 9, 3); SET_SA ($4); O1 ($4); }
  211. else
  212. NOT_SFR_OR_SADDR;
  213. }
  214. | andor1 CY ',' A '.' EXPR {Bit($6)}
  215. { B2 (0x71, 0x88|$1); FE ($6, 9, 3); }
  216. | andor1 CY ',' opt_es '[' HL ']' '.' EXPR {Bit($9)}
  217. { B2 (0x71, 0x80|$1); FE ($9, 9, 3); }
  218. /* ---------------------------------------------------------------------- */
  219. | BC '$' EXPR
  220. { B1 (0xdc); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
  221. | BNC '$' EXPR
  222. { B1 (0xde); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
  223. | BZ '$' EXPR
  224. { B1 (0xdd); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
  225. | BNZ '$' EXPR
  226. { B1 (0xdf); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
  227. | BH '$' EXPR
  228. { B2 (0x61, 0xc3); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
  229. | BNH '$' EXPR
  230. { B2 (0x61, 0xd3); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
  231. /* ---------------------------------------------------------------------- */
  232. | bt_bf sfr '.' EXPR ',' '$' EXPR
  233. { B3 (0x31, 0x80|$1, $2); FE ($4, 9, 3); PC1 ($7); }
  234. | bt_bf EXPR '.' EXPR ',' '$' EXPR
  235. { if (expr_is_sfr ($2))
  236. { B2 (0x31, 0x80|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); }
  237. else if (expr_is_saddr ($2))
  238. { B2 (0x31, 0x00|$1); FE ($4, 9, 3); SET_SA ($2); O1 ($2); PC1 ($7); }
  239. else
  240. NOT_SFR_OR_SADDR;
  241. }
  242. | bt_bf A '.' EXPR ',' '$' EXPR
  243. { B2 (0x31, 0x01|$1); FE ($4, 9, 3); PC1 ($7); }
  244. | bt_bf opt_es '[' HL ']' '.' EXPR ',' '$' EXPR
  245. { B2 (0x31, 0x81|$1); FE ($7, 9, 3); PC1 ($10); }
  246. /* ---------------------------------------------------------------------- */
  247. | BR AX
  248. { B2 (0x61, 0xcb); }
  249. | BR '$' EXPR
  250. { B1 (0xef); PC1 ($3); }
  251. | BR '$' '!' EXPR
  252. { B1 (0xee); PC2 ($4); rl78_linkrelax_branch (); }
  253. | BR '!' EXPR
  254. { B1 (0xed); O2 ($3); rl78_linkrelax_branch (); }
  255. | BR '!' '!' EXPR
  256. { B1 (0xec); O3 ($4); rl78_linkrelax_branch (); }
  257. /* ---------------------------------------------------------------------- */
  258. | BRK
  259. { B2 (0x61, 0xcc); }
  260. | BRK1
  261. { B1 (0xff); }
  262. /* ---------------------------------------------------------------------- */
  263. | CALL regw
  264. { B2 (0x61, 0xca); F ($2, 10, 2); }
  265. | CALL '$' '!' EXPR
  266. { B1 (0xfe); PC2 ($4); }
  267. | CALL '!' EXPR
  268. { B1 (0xfd); O2 ($3); }
  269. | CALL '!' '!' EXPR
  270. { B1 (0xfc); O3 ($4); rl78_linkrelax_branch (); }
  271. | CALLT '[' EXPR ']'
  272. { if ($3.X_op != O_constant)
  273. rl78_error ("CALLT requires a numeric address");
  274. else
  275. {
  276. int i = $3.X_add_number;
  277. if (i < 0x80 || i > 0xbe)
  278. rl78_error ("CALLT address not 0x80..0xbe");
  279. else if (i & 1)
  280. rl78_error ("CALLT address not even");
  281. else
  282. {
  283. B2 (0x61, 0x84);
  284. F ((i >> 1) & 7, 9, 3);
  285. F ((i >> 4) & 7, 14, 2);
  286. }
  287. }
  288. }
  289. /* ---------------------------------------------------------------------- */
  290. | setclr1 CY
  291. { B2 (0x71, $1 ? 0x88 : 0x80); }
  292. | setclr1 sfr '.' EXPR
  293. { B3 (0x71, 0x0a|$1, $2); FE ($4, 9, 3); }
  294. | setclr1 EXPR '.' EXPR
  295. { if (expr_is_sfr ($2))
  296. { B2 (0x71, 0x0a|$1); FE ($4, 9, 3); O1 ($2); }
  297. else if (expr_is_saddr ($2))
  298. { B2 (0x71, 0x02|$1); FE ($4, 9, 3); SET_SA ($2); O1 ($2); }
  299. else
  300. NOT_SFR_OR_SADDR;
  301. }
  302. | setclr1 A '.' EXPR
  303. { B2 (0x71, 0x8a|$1); FE ($4, 9, 3); }
  304. | setclr1 opt_es '!' EXPR '.' EXPR
  305. { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); rl78_linkrelax_addr16 (); }
  306. | setclr1 opt_es '[' HL ']' '.' EXPR
  307. { B2 (0x71, 0x82|$1); FE ($7, 9, 3); }
  308. /* ---------------------------------------------------------------------- */
  309. | oneclrb A
  310. { B1 (0xe1|$1); }
  311. | oneclrb X
  312. { B1 (0xe0|$1); }
  313. | oneclrb B
  314. { B1 (0xe3|$1); }
  315. | oneclrb C
  316. { B1 (0xe2|$1); }
  317. | oneclrb EXPR {SA($2)}
  318. { B1 (0xe4|$1); SET_SA ($2); O1 ($2); }
  319. | oneclrb opt_es '!' EXPR
  320. { B1 (0xe5|$1); O2 ($4); rl78_linkrelax_addr16 (); }
  321. /* ---------------------------------------------------------------------- */
  322. | oneclrw AX
  323. { B1 (0xe6|$1); }
  324. | oneclrw BC
  325. { B1 (0xe7|$1); }
  326. /* ---------------------------------------------------------------------- */
  327. | CMP0 A
  328. { B1 (0xd1); }
  329. | CMP0 X
  330. { B1 (0xd0); }
  331. | CMP0 B
  332. { B1 (0xd3); }
  333. | CMP0 C
  334. { B1 (0xd2); }
  335. | CMP0 EXPR {SA($2)}
  336. { B1 (0xd4); SET_SA ($2); O1 ($2); }
  337. | CMP0 opt_es '!' EXPR
  338. { B1 (0xd5); O2 ($4); rl78_linkrelax_addr16 (); }
  339. /* ---------------------------------------------------------------------- */
  340. | CMPS X ',' opt_es '[' HL '+' EXPR ']'
  341. { B2 (0x61, 0xde); O1 ($8); }
  342. /* ---------------------------------------------------------------------- */
  343. | incdec regb
  344. { B1 (0x80|$1); F ($2, 5, 3); }
  345. | incdec EXPR {SA($2)}
  346. { B1 (0xa4|$1); SET_SA ($2); O1 ($2); }
  347. | incdec '!' EXPR
  348. { B1 (0xa0|$1); O2 ($3); rl78_linkrelax_addr16 (); }
  349. | incdec ES ':' '!' EXPR
  350. { B2 (0x11, 0xa0|$1); O2 ($5); }
  351. | incdec '[' HL '+' EXPR ']'
  352. { B2 (0x61, 0x59+$1); O1 ($5); }
  353. | incdec ES ':' '[' HL '+' EXPR ']'
  354. { B3 (0x11, 0x61, 0x59+$1); O1 ($7); }
  355. /* ---------------------------------------------------------------------- */
  356. | incdecw regw
  357. { B1 (0xa1|$1); F ($2, 5, 2); }
  358. | incdecw EXPR {SA($2)}
  359. { B1 (0xa6|$1); SET_SA ($2); O1 ($2); }
  360. | incdecw opt_es '!' EXPR
  361. { B1 (0xa2|$1); O2 ($4); rl78_linkrelax_addr16 (); }
  362. | incdecw opt_es '[' HL '+' EXPR ']'
  363. { B2 (0x61, 0x79+$1); O1 ($6); }
  364. /* ---------------------------------------------------------------------- */
  365. | DI
  366. { B3 (0x71, 0x7b, 0xfa); }
  367. | EI
  368. { B3 (0x71, 0x7a, 0xfa); }
  369. /* ---------------------------------------------------------------------- */
  370. | MULHU { ISA_G14 ("MULHU"); }
  371. { B3 (0xce, 0xfb, 0x01); }
  372. | MULH { ISA_G14 ("MULH"); }
  373. { B3 (0xce, 0xfb, 0x02); }
  374. | MULU X
  375. { B1 (0xd6); }
  376. | DIVHU { ISA_G14 ("DIVHU"); }
  377. { B3 (0xce, 0xfb, 0x03); }
  378. /* Note that the DIVWU encoding was changed from [0xce,0xfb,0x04] to
  379. [0xce,0xfb,0x0b]. Different versions of the Software Manual exist
  380. with the same version number, but varying encodings. The version
  381. here matches the hardware. */
  382. | DIVWU { ISA_G14 ("DIVWU"); }
  383. { B3 (0xce, 0xfb, 0x0b); }
  384. | MACHU { ISA_G14 ("MACHU"); }
  385. { B3 (0xce, 0xfb, 0x05); }
  386. | MACH { ISA_G14 ("MACH"); }
  387. { B3 (0xce, 0xfb, 0x06); }
  388. /* ---------------------------------------------------------------------- */
  389. | HALT
  390. { B2 (0x61, 0xed); }
  391. /* ---------------------------------------------------------------------- */
  392. /* Note that opt_es is included even when it's not an option, to avoid
  393. shift/reduce conflicts. The NOT_ES macro produces an error if ES:
  394. is given by the user. */
  395. | MOV A ',' '#' EXPR
  396. { B1 (0x51); O1 ($5); }
  397. | MOV regb_na ',' '#' EXPR
  398. { B1 (0x50); F($2, 5, 3); O1 ($5); }
  399. | MOV sfr ',' '#' EXPR
  400. { if ($2 != 0xfd)
  401. { B2 (0xce, $2); O1 ($5); }
  402. else
  403. { B1 (0x41); O1 ($5); }
  404. }
  405. | MOV opt_es EXPR ',' '#' EXPR {NOT_ES}
  406. { if (expr_is_sfr ($3))
  407. { B1 (0xce); O1 ($3); O1 ($6); }
  408. else if (expr_is_saddr ($3))
  409. { B1 (0xcd); SET_SA ($3); O1 ($3); O1 ($6); }
  410. else
  411. NOT_SFR_OR_SADDR;
  412. }
  413. | MOV '!' EXPR ',' '#' EXPR
  414. { B1 (0xcf); O2 ($3); O1 ($6); rl78_linkrelax_addr16 (); }
  415. | MOV ES ':' '!' EXPR ',' '#' EXPR
  416. { B2 (0x11, 0xcf); O2 ($5); O1 ($8); }
  417. | MOV regb_na ',' A
  418. { B1 (0x70); F ($2, 5, 3); }
  419. | MOV A ',' regb_na
  420. { B1 (0x60); F ($4, 5, 3); }
  421. | MOV opt_es EXPR ',' A {NOT_ES}
  422. { if (expr_is_sfr ($3))
  423. { B1 (0x9e); O1 ($3); }
  424. else if (expr_is_saddr ($3))
  425. { B1 (0x9d); SET_SA ($3); O1 ($3); }
  426. else
  427. NOT_SFR_OR_SADDR;
  428. }
  429. | MOV A ',' opt_es '!' EXPR
  430. { B1 (0x8f); O2 ($6); rl78_linkrelax_addr16 (); }
  431. | MOV '!' EXPR ',' A
  432. { B1 (0x9f); O2 ($3); rl78_linkrelax_addr16 (); }
  433. | MOV ES ':' '!' EXPR ',' A
  434. { B2 (0x11, 0x9f); O2 ($5); }
  435. | MOV regb_na ',' opt_es '!' EXPR
  436. { B1 (0xc9|reg_xbc($2)); O2 ($6); rl78_linkrelax_addr16 (); }
  437. | MOV A ',' opt_es EXPR {NOT_ES}
  438. { if (expr_is_saddr ($5))
  439. { B1 (0x8d); SET_SA ($5); O1 ($5); }
  440. else if (expr_is_sfr ($5))
  441. { B1 (0x8e); O1 ($5); }
  442. else
  443. NOT_SFR_OR_SADDR;
  444. }
  445. | MOV regb_na ',' opt_es EXPR {SA($5)} {NOT_ES}
  446. { B1 (0xc8|reg_xbc($2)); SET_SA ($5); O1 ($5); }
  447. | MOV A ',' sfr
  448. { B2 (0x8e, $4); }
  449. | MOV sfr ',' regb
  450. { if ($4 != 1)
  451. rl78_error ("Only A allowed here");
  452. else
  453. { B2 (0x9e, $2); }
  454. }
  455. | MOV sfr ',' opt_es EXPR {SA($5)} {NOT_ES}
  456. { if ($2 != 0xfd)
  457. rl78_error ("Only ES allowed here");
  458. else
  459. { B2 (0x61, 0xb8); SET_SA ($5); O1 ($5); }
  460. }
  461. | MOV A ',' opt_es '[' DE ']'
  462. { B1 (0x89); }
  463. | MOV opt_es '[' DE ']' ',' A
  464. { B1 (0x99); }
  465. | MOV opt_es '[' DE '+' EXPR ']' ',' '#' EXPR
  466. { B1 (0xca); O1 ($6); O1 ($10); }
  467. | MOV A ',' opt_es '[' DE '+' EXPR ']'
  468. { B1 (0x8a); O1 ($8); }
  469. | MOV opt_es '[' DE '+' EXPR ']' ',' A
  470. { B1 (0x9a); O1 ($6); }
  471. | MOV A ',' opt_es '[' HL ']'
  472. { B1 (0x8b); }
  473. | MOV opt_es '[' HL ']' ',' A
  474. { B1 (0x9b); }
  475. | MOV opt_es '[' HL '+' EXPR ']' ',' '#' EXPR
  476. { B1 (0xcc); O1 ($6); O1 ($10); }
  477. | MOV A ',' opt_es '[' HL '+' EXPR ']'
  478. { B1 (0x8c); O1 ($8); }
  479. | MOV opt_es '[' HL '+' EXPR ']' ',' A
  480. { B1 (0x9c); O1 ($6); }
  481. | MOV A ',' opt_es '[' HL '+' B ']'
  482. { B2 (0x61, 0xc9); }
  483. | MOV opt_es '[' HL '+' B ']' ',' A
  484. { B2 (0x61, 0xd9); }
  485. | MOV A ',' opt_es '[' HL '+' C ']'
  486. { B2 (0x61, 0xe9); }
  487. | MOV opt_es '[' HL '+' C ']' ',' A
  488. { B2 (0x61, 0xf9); }
  489. | MOV opt_es EXPR '[' B ']' ',' '#' EXPR
  490. { B1 (0x19); O2 ($3); O1 ($9); }
  491. | MOV A ',' opt_es EXPR '[' B ']'
  492. { B1 (0x09); O2 ($5); }
  493. | MOV opt_es EXPR '[' B ']' ',' A
  494. { B1 (0x18); O2 ($3); }
  495. | MOV opt_es EXPR '[' C ']' ',' '#' EXPR
  496. { B1 (0x38); O2 ($3); O1 ($9); }
  497. | MOV A ',' opt_es EXPR '[' C ']'
  498. { B1 (0x29); O2 ($5); }
  499. | MOV opt_es EXPR '[' C ']' ',' A
  500. { B1 (0x28); O2 ($3); }
  501. | MOV opt_es EXPR '[' BC ']' ',' '#' EXPR
  502. { B1 (0x39); O2 ($3); O1 ($9); }
  503. | MOV opt_es '[' BC ']' ',' '#' EXPR
  504. { B3 (0x39, 0, 0); O1 ($8); }
  505. | MOV A ',' opt_es EXPR '[' BC ']'
  506. { B1 (0x49); O2 ($5); }
  507. | MOV A ',' opt_es '[' BC ']'
  508. { B3 (0x49, 0, 0); }
  509. | MOV opt_es EXPR '[' BC ']' ',' A
  510. { B1 (0x48); O2 ($3); }
  511. | MOV opt_es '[' BC ']' ',' A
  512. { B3 (0x48, 0, 0); }
  513. | MOV opt_es '[' SP '+' EXPR ']' ',' '#' EXPR {NOT_ES}
  514. { B1 (0xc8); O1 ($6); O1 ($10); }
  515. | MOV opt_es '[' SP ']' ',' '#' EXPR {NOT_ES}
  516. { B2 (0xc8, 0); O1 ($8); }
  517. | MOV A ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
  518. { B1 (0x88); O1 ($8); }
  519. | MOV A ',' opt_es '[' SP ']' {NOT_ES}
  520. { B2 (0x88, 0); }
  521. | MOV opt_es '[' SP '+' EXPR ']' ',' A {NOT_ES}
  522. { B1 (0x98); O1 ($6); }
  523. | MOV opt_es '[' SP ']' ',' A {NOT_ES}
  524. { B2 (0x98, 0); }
  525. /* ---------------------------------------------------------------------- */
  526. | mov1 CY ',' EXPR '.' EXPR
  527. { if (expr_is_saddr ($4))
  528. { B2 (0x71, 0x04); FE ($6, 9, 3); SET_SA ($4); O1 ($4); }
  529. else if (expr_is_sfr ($4))
  530. { B2 (0x71, 0x0c); FE ($6, 9, 3); O1 ($4); }
  531. else
  532. NOT_SFR_OR_SADDR;
  533. }
  534. | mov1 CY ',' A '.' EXPR
  535. { B2 (0x71, 0x8c); FE ($6, 9, 3); }
  536. | mov1 CY ',' sfr '.' EXPR
  537. { B3 (0x71, 0x0c, $4); FE ($6, 9, 3); }
  538. | mov1 CY ',' opt_es '[' HL ']' '.' EXPR
  539. { B2 (0x71, 0x84); FE ($9, 9, 3); }
  540. | mov1 EXPR '.' EXPR ',' CY
  541. { if (expr_is_saddr ($2))
  542. { B2 (0x71, 0x01); FE ($4, 9, 3); SET_SA ($2); O1 ($2); }
  543. else if (expr_is_sfr ($2))
  544. { B2 (0x71, 0x09); FE ($4, 9, 3); O1 ($2); }
  545. else
  546. NOT_SFR_OR_SADDR;
  547. }
  548. | mov1 A '.' EXPR ',' CY
  549. { B2 (0x71, 0x89); FE ($4, 9, 3); }
  550. | mov1 sfr '.' EXPR ',' CY
  551. { B3 (0x71, 0x09, $2); FE ($4, 9, 3); }
  552. | mov1 opt_es '[' HL ']' '.' EXPR ',' CY
  553. { B2 (0x71, 0x81); FE ($7, 9, 3); }
  554. /* ---------------------------------------------------------------------- */
  555. | MOVS opt_es '[' HL '+' EXPR ']' ',' X
  556. { B2 (0x61, 0xce); O1 ($6); }
  557. /* ---------------------------------------------------------------------- */
  558. | MOVW AX ',' '#' EXPR
  559. { B1 (0x30); O2 ($5); }
  560. | MOVW regw_na ',' '#' EXPR
  561. { B1 (0x30); F ($2, 5, 2); O2 ($5); }
  562. | MOVW opt_es EXPR ',' '#' EXPR {NOT_ES}
  563. { if (expr_is_saddr ($3))
  564. { B1 (0xc9); SET_SA ($3); O1 ($3); O2 ($6); }
  565. else if (expr_is_sfr ($3))
  566. { B1 (0xcb); O1 ($3); O2 ($6); }
  567. else
  568. NOT_SFR_OR_SADDR;
  569. }
  570. | MOVW AX ',' opt_es EXPR {NOT_ES}
  571. { if (expr_is_saddr ($5))
  572. { B1 (0xad); SET_SA ($5); O1 ($5); WA($5); }
  573. else if (expr_is_sfr ($5))
  574. { B1 (0xae); O1 ($5); WA($5); }
  575. else
  576. NOT_SFR_OR_SADDR;
  577. }
  578. | MOVW opt_es EXPR ',' AX {NOT_ES}
  579. { if (expr_is_saddr ($3))
  580. { B1 (0xbd); SET_SA ($3); O1 ($3); WA($3); }
  581. else if (expr_is_sfr ($3))
  582. { B1 (0xbe); O1 ($3); WA($3); }
  583. else
  584. NOT_SFR_OR_SADDR;
  585. }
  586. | MOVW AX ',' regw_na
  587. { B1 (0x11); F ($4, 5, 2); }
  588. | MOVW regw_na ',' AX
  589. { B1 (0x10); F ($2, 5, 2); }
  590. | MOVW AX ',' opt_es '!' EXPR
  591. { B1 (0xaf); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
  592. | MOVW opt_es '!' EXPR ',' AX
  593. { B1 (0xbf); O2 ($4); WA($4); rl78_linkrelax_addr16 (); }
  594. | MOVW AX ',' opt_es '[' DE ']'
  595. { B1 (0xa9); }
  596. | MOVW opt_es '[' DE ']' ',' AX
  597. { B1 (0xb9); }
  598. | MOVW AX ',' opt_es '[' DE '+' EXPR ']'
  599. { B1 (0xaa); O1 ($8); }
  600. | MOVW opt_es '[' DE '+' EXPR ']' ',' AX
  601. { B1 (0xba); O1 ($6); }
  602. | MOVW AX ',' opt_es '[' HL ']'
  603. { B1 (0xab); }
  604. | MOVW opt_es '[' HL ']' ',' AX
  605. { B1 (0xbb); }
  606. | MOVW AX ',' opt_es '[' HL '+' EXPR ']'
  607. { B1 (0xac); O1 ($8); }
  608. | MOVW opt_es '[' HL '+' EXPR ']' ',' AX
  609. { B1 (0xbc); O1 ($6); }
  610. | MOVW AX ',' opt_es EXPR '[' B ']'
  611. { B1 (0x59); O2 ($5); }
  612. | MOVW opt_es EXPR '[' B ']' ',' AX
  613. { B1 (0x58); O2 ($3); }
  614. | MOVW AX ',' opt_es EXPR '[' C ']'
  615. { B1 (0x69); O2 ($5); }
  616. | MOVW opt_es EXPR '[' C ']' ',' AX
  617. { B1 (0x68); O2 ($3); }
  618. | MOVW AX ',' opt_es EXPR '[' BC ']'
  619. { B1 (0x79); O2 ($5); }
  620. | MOVW AX ',' opt_es '[' BC ']'
  621. { B3 (0x79, 0, 0); }
  622. | MOVW opt_es EXPR '[' BC ']' ',' AX
  623. { B1 (0x78); O2 ($3); }
  624. | MOVW opt_es '[' BC ']' ',' AX
  625. { B3 (0x78, 0, 0); }
  626. | MOVW AX ',' opt_es '[' SP '+' EXPR ']' {NOT_ES}
  627. { B1 (0xa8); O1 ($8); WA($8);}
  628. | MOVW AX ',' opt_es '[' SP ']' {NOT_ES}
  629. { B2 (0xa8, 0); }
  630. | MOVW opt_es '[' SP '+' EXPR ']' ',' AX {NOT_ES}
  631. { B1 (0xb8); O1 ($6); WA($6); }
  632. | MOVW opt_es '[' SP ']' ',' AX {NOT_ES}
  633. { B2 (0xb8, 0); }
  634. | MOVW regw_na ',' EXPR {SA($4)}
  635. { B1 (0xca); F ($2, 2, 2); SET_SA ($4); O1 ($4); WA($4); }
  636. | MOVW regw_na ',' opt_es '!' EXPR
  637. { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
  638. | MOVW SP ',' '#' EXPR
  639. { B2 (0xcb, 0xf8); O2 ($5); }
  640. | MOVW SP ',' AX
  641. { B2 (0xbe, 0xf8); }
  642. | MOVW AX ',' SP
  643. { B2 (0xae, 0xf8); }
  644. | MOVW regw_na ',' SP
  645. { B3 (0xcb, 0xf8, 0xff); F ($2, 2, 2); }
  646. /* ---------------------------------------------------------------------- */
  647. | NOP
  648. { B1 (0x00); }
  649. /* ---------------------------------------------------------------------- */
  650. | NOT1 CY
  651. { B2 (0x71, 0xc0); }
  652. /* ---------------------------------------------------------------------- */
  653. | POP regw
  654. { B1 (0xc0); F ($2, 5, 2); }
  655. | POP PSW
  656. { B2 (0x61, 0xcd); };
  657. | PUSH regw
  658. { B1 (0xc1); F ($2, 5, 2); }
  659. | PUSH PSW
  660. { B2 (0x61, 0xdd); };
  661. /* ---------------------------------------------------------------------- */
  662. | RET
  663. { B1 (0xd7); }
  664. | RETI
  665. { B2 (0x61, 0xfc); }
  666. | RETB
  667. { B2 (0x61, 0xec); }
  668. /* ---------------------------------------------------------------------- */
  669. | ROL A ',' EXPR
  670. { if (check_expr_is_const ($4, 1, 1))
  671. { B2 (0x61, 0xeb); }
  672. }
  673. | ROLC A ',' EXPR
  674. { if (check_expr_is_const ($4, 1, 1))
  675. { B2 (0x61, 0xdc); }
  676. }
  677. | ROLWC AX ',' EXPR
  678. { if (check_expr_is_const ($4, 1, 1))
  679. { B2 (0x61, 0xee); }
  680. }
  681. | ROLWC BC ',' EXPR
  682. { if (check_expr_is_const ($4, 1, 1))
  683. { B2 (0x61, 0xfe); }
  684. }
  685. | ROR A ',' EXPR
  686. { if (check_expr_is_const ($4, 1, 1))
  687. { B2 (0x61, 0xdb); }
  688. }
  689. | RORC A ',' EXPR
  690. { if (check_expr_is_const ($4, 1, 1))
  691. { B2 (0x61, 0xfb);}
  692. }
  693. /* ---------------------------------------------------------------------- */
  694. | SAR A ',' EXPR
  695. { if (check_expr_is_const ($4, 1, 7))
  696. { B2 (0x31, 0x0b); FE ($4, 9, 3); }
  697. }
  698. | SARW AX ',' EXPR
  699. { if (check_expr_is_const ($4, 1, 15))
  700. { B2 (0x31, 0x0f); FE ($4, 8, 4); }
  701. }
  702. /* ---------------------------------------------------------------------- */
  703. | SEL RB0
  704. { B2 (0x61, 0xcf); }
  705. | SEL RB1
  706. { B2 (0x61, 0xdf); }
  707. | SEL RB2
  708. { B2 (0x61, 0xef); }
  709. | SEL RB3
  710. { B2 (0x61, 0xff); }
  711. /* ---------------------------------------------------------------------- */
  712. | SHL A ',' EXPR
  713. { if (check_expr_is_const ($4, 1, 7))
  714. { B2 (0x31, 0x09); FE ($4, 9, 3); }
  715. }
  716. | SHL B ',' EXPR
  717. { if (check_expr_is_const ($4, 1, 7))
  718. { B2 (0x31, 0x08); FE ($4, 9, 3); }
  719. }
  720. | SHL C ',' EXPR
  721. { if (check_expr_is_const ($4, 1, 7))
  722. { B2 (0x31, 0x07); FE ($4, 9, 3); }
  723. }
  724. | SHLW AX ',' EXPR
  725. { if (check_expr_is_const ($4, 1, 15))
  726. { B2 (0x31, 0x0d); FE ($4, 8, 4); }
  727. }
  728. | SHLW BC ',' EXPR
  729. { if (check_expr_is_const ($4, 1, 15))
  730. { B2 (0x31, 0x0c); FE ($4, 8, 4); }
  731. }
  732. /* ---------------------------------------------------------------------- */
  733. | SHR A ',' EXPR
  734. { if (check_expr_is_const ($4, 1, 7))
  735. { B2 (0x31, 0x0a); FE ($4, 9, 3); }
  736. }
  737. | SHRW AX ',' EXPR
  738. { if (check_expr_is_const ($4, 1, 15))
  739. { B2 (0x31, 0x0e); FE ($4, 8, 4); }
  740. }
  741. /* ---------------------------------------------------------------------- */
  742. | SKC
  743. { B2 (0x61, 0xc8); rl78_linkrelax_branch (); }
  744. | SKH
  745. { B2 (0x61, 0xe3); rl78_linkrelax_branch (); }
  746. | SKNC
  747. { B2 (0x61, 0xd8); rl78_linkrelax_branch (); }
  748. | SKNH
  749. { B2 (0x61, 0xf3); rl78_linkrelax_branch (); }
  750. | SKNZ
  751. { B2 (0x61, 0xf8); rl78_linkrelax_branch (); }
  752. | SKZ
  753. { B2 (0x61, 0xe8); rl78_linkrelax_branch (); }
  754. /* ---------------------------------------------------------------------- */
  755. | STOP
  756. { B2 (0x61, 0xfd); }
  757. /* ---------------------------------------------------------------------- */
  758. | XCH A ',' regb_na
  759. { if ($4 == 0) /* X */
  760. { B1 (0x08); }
  761. else
  762. { B2 (0x61, 0x88); F ($4, 13, 3); }
  763. }
  764. | XCH A ',' opt_es '!' EXPR
  765. { B2 (0x61, 0xaa); O2 ($6); rl78_linkrelax_addr16 (); }
  766. | XCH A ',' opt_es '[' DE ']'
  767. { B2 (0x61, 0xae); }
  768. | XCH A ',' opt_es '[' DE '+' EXPR ']'
  769. { B2 (0x61, 0xaf); O1 ($8); }
  770. | XCH A ',' opt_es '[' HL ']'
  771. { B2 (0x61, 0xac); }
  772. | XCH A ',' opt_es '[' HL '+' EXPR ']'
  773. { B2 (0x61, 0xad); O1 ($8); }
  774. | XCH A ',' opt_es '[' HL '+' B ']'
  775. { B2 (0x61, 0xb9); }
  776. | XCH A ',' opt_es '[' HL '+' C ']'
  777. { B2 (0x61, 0xa9); }
  778. | XCH A ',' EXPR
  779. { if (expr_is_sfr ($4))
  780. { B2 (0x61, 0xab); O1 ($4); }
  781. else if (expr_is_saddr ($4))
  782. { B2 (0x61, 0xa8); SET_SA ($4); O1 ($4); }
  783. else
  784. NOT_SFR_OR_SADDR;
  785. }
  786. /* ---------------------------------------------------------------------- */
  787. | XCHW AX ',' regw_na
  788. { B1 (0x31); F ($4, 5, 2); }
  789. /* ---------------------------------------------------------------------- */
  790. ; /* end of statement */
  791. /* ---------------------------------------------------------------------- */
  792. opt_es : /* nothing */
  793. | ES ':'
  794. { rl78_prefix (0x11); }
  795. ;
  796. regb : X { $$ = 0; }
  797. | A { $$ = 1; }
  798. | C { $$ = 2; }
  799. | B { $$ = 3; }
  800. | E { $$ = 4; }
  801. | D { $$ = 5; }
  802. | L { $$ = 6; }
  803. | H { $$ = 7; }
  804. ;
  805. regb_na : X { $$ = 0; }
  806. | C { $$ = 2; }
  807. | B { $$ = 3; }
  808. | E { $$ = 4; }
  809. | D { $$ = 5; }
  810. | L { $$ = 6; }
  811. | H { $$ = 7; }
  812. ;
  813. regw : AX { $$ = 0; }
  814. | BC { $$ = 1; }
  815. | DE { $$ = 2; }
  816. | HL { $$ = 3; }
  817. ;
  818. regw_na : BC { $$ = 1; }
  819. | DE { $$ = 2; }
  820. | HL { $$ = 3; }
  821. ;
  822. sfr : SPL { $$ = 0xf8; }
  823. | SPH { $$ = 0xf9; }
  824. | PSW { $$ = 0xfa; }
  825. | CS { $$ = 0xfc; }
  826. | ES { $$ = 0xfd; }
  827. | PMC { $$ = 0xfe; }
  828. | MEM { $$ = 0xff; }
  829. ;
  830. /* ---------------------------------------------------------------------- */
  831. /* Shortcuts for groups of opcodes with common encodings. */
  832. addsub : ADD { $$ = 0x00; }
  833. | ADDC { $$ = 0x10; }
  834. | SUB { $$ = 0x20; }
  835. | SUBC { $$ = 0x30; }
  836. | CMP { $$ = 0x40; }
  837. | AND_ { $$ = 0x50; }
  838. | OR { $$ = 0x60; }
  839. | XOR { $$ = 0x70; }
  840. ;
  841. addsubw : ADDW { $$ = 0x00; }
  842. | SUBW { $$ = 0x20; }
  843. | CMPW { $$ = 0x40; }
  844. ;
  845. andor1 : AND1 { $$ = 0x05; rl78_bit_insn = 1; }
  846. | OR1 { $$ = 0x06; rl78_bit_insn = 1; }
  847. | XOR1 { $$ = 0x07; rl78_bit_insn = 1; }
  848. ;
  849. bt_bf : BT { $$ = 0x02; rl78_bit_insn = 1; rl78_relax (RL78_RELAX_BRANCH, 0); }
  850. | BF { $$ = 0x04; rl78_bit_insn = 1; rl78_relax (RL78_RELAX_BRANCH, 0); }
  851. | BTCLR { $$ = 0x00; rl78_bit_insn = 1; }
  852. ;
  853. setclr1 : SET1 { $$ = 0; rl78_bit_insn = 1; }
  854. | CLR1 { $$ = 1; rl78_bit_insn = 1; }
  855. ;
  856. oneclrb : ONEB { $$ = 0x00; }
  857. | CLRB { $$ = 0x10; }
  858. ;
  859. oneclrw : ONEW { $$ = 0x00; }
  860. | CLRW { $$ = 0x10; }
  861. ;
  862. incdec : INC { $$ = 0x00; }
  863. | DEC { $$ = 0x10; }
  864. ;
  865. incdecw : INCW { $$ = 0x00; }
  866. | DECW { $$ = 0x10; }
  867. ;
  868. mov1 : MOV1 { rl78_bit_insn = 1; }
  869. ;
  870. %%
  871. /* ====================================================================== */
  872. static struct
  873. {
  874. const char * string;
  875. int token;
  876. int val;
  877. }
  878. token_table[] =
  879. {
  880. { "r0", X, 0 },
  881. { "r1", A, 1 },
  882. { "r2", C, 2 },
  883. { "r3", B, 3 },
  884. { "r4", E, 4 },
  885. { "r5", D, 5 },
  886. { "r6", L, 6 },
  887. { "r7", H, 7 },
  888. { "x", X, 0 },
  889. { "a", A, 1 },
  890. { "c", C, 2 },
  891. { "b", B, 3 },
  892. { "e", E, 4 },
  893. { "d", D, 5 },
  894. { "l", L, 6 },
  895. { "h", H, 7 },
  896. { "rp0", AX, 0 },
  897. { "rp1", BC, 1 },
  898. { "rp2", DE, 2 },
  899. { "rp3", HL, 3 },
  900. { "ax", AX, 0 },
  901. { "bc", BC, 1 },
  902. { "de", DE, 2 },
  903. { "hl", HL, 3 },
  904. { "RB0", RB0, 0 },
  905. { "RB1", RB1, 1 },
  906. { "RB2", RB2, 2 },
  907. { "RB3", RB3, 3 },
  908. { "sp", SP, 0 },
  909. { "cy", CY, 0 },
  910. { "spl", SPL, 0xf8 },
  911. { "sph", SPH, 0xf9 },
  912. { "psw", PSW, 0xfa },
  913. { "cs", CS, 0xfc },
  914. { "es", ES, 0xfd },
  915. { "pmc", PMC, 0xfe },
  916. { "mem", MEM, 0xff },
  917. { ".s", DOT_S, 0 },
  918. { ".b", DOT_B, 0 },
  919. { ".w", DOT_W, 0 },
  920. { ".l", DOT_L, 0 },
  921. { ".a", DOT_A , 0},
  922. { ".ub", DOT_UB, 0 },
  923. { ".uw", DOT_UW , 0},
  924. { "c", FLAG, 0 },
  925. { "z", FLAG, 1 },
  926. { "s", FLAG, 2 },
  927. { "o", FLAG, 3 },
  928. { "i", FLAG, 8 },
  929. { "u", FLAG, 9 },
  930. #define OPC(x) { #x, x, IS_OPCODE }
  931. OPC(ADD),
  932. OPC(ADDC),
  933. OPC(ADDW),
  934. { "and", AND_, IS_OPCODE },
  935. OPC(AND1),
  936. OPC(BC),
  937. OPC(BF),
  938. OPC(BH),
  939. OPC(BNC),
  940. OPC(BNH),
  941. OPC(BNZ),
  942. OPC(BR),
  943. OPC(BRK),
  944. OPC(BRK1),
  945. OPC(BT),
  946. OPC(BTCLR),
  947. OPC(BZ),
  948. OPC(CALL),
  949. OPC(CALLT),
  950. OPC(CLR1),
  951. OPC(CLRB),
  952. OPC(CLRW),
  953. OPC(CMP),
  954. OPC(CMP0),
  955. OPC(CMPS),
  956. OPC(CMPW),
  957. OPC(DEC),
  958. OPC(DECW),
  959. OPC(DI),
  960. OPC(DIVHU),
  961. OPC(DIVWU),
  962. OPC(EI),
  963. OPC(HALT),
  964. OPC(INC),
  965. OPC(INCW),
  966. OPC(MACH),
  967. OPC(MACHU),
  968. OPC(MOV),
  969. OPC(MOV1),
  970. OPC(MOVS),
  971. OPC(MOVW),
  972. OPC(MULH),
  973. OPC(MULHU),
  974. OPC(MULU),
  975. OPC(NOP),
  976. OPC(NOT1),
  977. OPC(ONEB),
  978. OPC(ONEW),
  979. OPC(OR),
  980. OPC(OR1),
  981. OPC(POP),
  982. OPC(PUSH),
  983. OPC(RET),
  984. OPC(RETI),
  985. OPC(RETB),
  986. OPC(ROL),
  987. OPC(ROLC),
  988. OPC(ROLWC),
  989. OPC(ROR),
  990. OPC(RORC),
  991. OPC(SAR),
  992. OPC(SARW),
  993. OPC(SEL),
  994. OPC(SET1),
  995. OPC(SHL),
  996. OPC(SHLW),
  997. OPC(SHR),
  998. OPC(SHRW),
  999. OPC(SKC),
  1000. OPC(SKH),
  1001. OPC(SKNC),
  1002. OPC(SKNH),
  1003. OPC(SKNZ),
  1004. OPC(SKZ),
  1005. OPC(STOP),
  1006. OPC(SUB),
  1007. OPC(SUBC),
  1008. OPC(SUBW),
  1009. OPC(XCH),
  1010. OPC(XCHW),
  1011. OPC(XOR),
  1012. OPC(XOR1),
  1013. };
  1014. #define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0]))
  1015. void
  1016. rl78_lex_init (char * beginning, char * ending)
  1017. {
  1018. rl78_init_start = beginning;
  1019. rl78_lex_start = beginning;
  1020. rl78_lex_end = ending;
  1021. rl78_in_brackets = 0;
  1022. rl78_last_token = 0;
  1023. rl78_bit_insn = 0;
  1024. setbuf (stdout, 0);
  1025. }
  1026. /* Return a pointer to the '.' in a bit index expression (like
  1027. foo.5), or NULL if none is found. */
  1028. static char *
  1029. find_bit_index (char *tok)
  1030. {
  1031. char *last_dot = NULL;
  1032. char *last_digit = NULL;
  1033. while (*tok && *tok != ',')
  1034. {
  1035. if (*tok == '.')
  1036. {
  1037. last_dot = tok;
  1038. last_digit = NULL;
  1039. }
  1040. else if (*tok >= '0' && *tok <= '7'
  1041. && last_dot != NULL
  1042. && last_digit == NULL)
  1043. {
  1044. last_digit = tok;
  1045. }
  1046. else if (ISSPACE (*tok))
  1047. {
  1048. /* skip */
  1049. }
  1050. else
  1051. {
  1052. last_dot = NULL;
  1053. last_digit = NULL;
  1054. }
  1055. tok ++;
  1056. }
  1057. if (last_dot != NULL
  1058. && last_digit != NULL)
  1059. return last_dot;
  1060. return NULL;
  1061. }
  1062. static int
  1063. rl78_lex (void)
  1064. {
  1065. /*unsigned int ci;*/
  1066. char * save_input_pointer;
  1067. char * bit = NULL;
  1068. while (ISSPACE (*rl78_lex_start)
  1069. && rl78_lex_start != rl78_lex_end)
  1070. rl78_lex_start ++;
  1071. rl78_last_exp_start = rl78_lex_start;
  1072. if (rl78_lex_start == rl78_lex_end)
  1073. return 0;
  1074. if (ISALPHA (*rl78_lex_start)
  1075. || (*rl78_lex_start == '.' && ISALPHA (rl78_lex_start[1])))
  1076. {
  1077. unsigned int i;
  1078. char * e;
  1079. char save;
  1080. for (e = rl78_lex_start + 1;
  1081. e < rl78_lex_end && ISALNUM (*e);
  1082. e ++)
  1083. ;
  1084. save = *e;
  1085. *e = 0;
  1086. for (i = 0; i < NUM_TOKENS; i++)
  1087. if (strcasecmp (rl78_lex_start, token_table[i].string) == 0
  1088. && !(token_table[i].val == IS_OPCODE && rl78_last_token != 0)
  1089. && !(token_table[i].token == FLAG && !need_flag))
  1090. {
  1091. rl78_lval.regno = token_table[i].val;
  1092. *e = save;
  1093. rl78_lex_start = e;
  1094. rl78_last_token = token_table[i].token;
  1095. return token_table[i].token;
  1096. }
  1097. *e = save;
  1098. }
  1099. if (rl78_last_token == 0)
  1100. {
  1101. rl78_last_token = UNKNOWN_OPCODE;
  1102. return UNKNOWN_OPCODE;
  1103. }
  1104. if (rl78_last_token == UNKNOWN_OPCODE)
  1105. return 0;
  1106. if (*rl78_lex_start == '[')
  1107. rl78_in_brackets = 1;
  1108. if (*rl78_lex_start == ']')
  1109. rl78_in_brackets = 0;
  1110. /* '.' is funny - the syntax includes it for bitfields, but only for
  1111. bitfields. We check for it specially so we can allow labels
  1112. with '.' in them. */
  1113. if (rl78_bit_insn
  1114. && *rl78_lex_start == '.'
  1115. && find_bit_index (rl78_lex_start) == rl78_lex_start)
  1116. {
  1117. rl78_last_token = *rl78_lex_start;
  1118. return *rl78_lex_start ++;
  1119. }
  1120. if ((rl78_in_brackets && *rl78_lex_start == '+')
  1121. || strchr ("[],#!$:", *rl78_lex_start))
  1122. {
  1123. rl78_last_token = *rl78_lex_start;
  1124. return *rl78_lex_start ++;
  1125. }
  1126. /* Again, '.' is funny. Look for '.<digit>' at the end of the line
  1127. or before a comma, which is a bitfield, not an expression. */
  1128. if (rl78_bit_insn)
  1129. {
  1130. bit = find_bit_index (rl78_lex_start);
  1131. if (bit)
  1132. *bit = 0;
  1133. else
  1134. bit = NULL;
  1135. }
  1136. save_input_pointer = input_line_pointer;
  1137. input_line_pointer = rl78_lex_start;
  1138. rl78_lval.exp.X_md = 0;
  1139. expression (&rl78_lval.exp);
  1140. if (bit)
  1141. *bit = '.';
  1142. rl78_lex_start = input_line_pointer;
  1143. input_line_pointer = save_input_pointer;
  1144. rl78_last_token = EXPR;
  1145. return EXPR;
  1146. }
  1147. int
  1148. rl78_error (const char * str)
  1149. {
  1150. int len;
  1151. len = rl78_last_exp_start - rl78_init_start;
  1152. as_bad ("%s", rl78_init_start);
  1153. as_bad ("%*s^ %s", len, "", str);
  1154. return 0;
  1155. }
  1156. static int
  1157. expr_is_sfr (expressionS exp)
  1158. {
  1159. unsigned long v;
  1160. if (exp.X_op != O_constant)
  1161. return 0;
  1162. v = exp.X_add_number;
  1163. if (0xFFF00 <= v && v <= 0xFFFFF)
  1164. return 1;
  1165. return 0;
  1166. }
  1167. static int
  1168. expr_is_saddr (expressionS exp)
  1169. {
  1170. unsigned long v;
  1171. if (exp.X_op != O_constant)
  1172. return 1;
  1173. v = exp.X_add_number;
  1174. if (0xFFE20 <= v && v <= 0xFFF1F)
  1175. return 1;
  1176. return 0;
  1177. }
  1178. static int
  1179. expr_is_word_aligned (expressionS exp)
  1180. {
  1181. unsigned long v;
  1182. if (exp.X_op != O_constant)
  1183. return 1;
  1184. v = exp.X_add_number;
  1185. if (v & 1)
  1186. return 0;
  1187. return 1;
  1188. }
  1189. static void
  1190. check_expr_is_bit_index (expressionS exp)
  1191. {
  1192. int val;
  1193. if (exp.X_op != O_constant)
  1194. {
  1195. rl78_error (_("bit index must be a constant"));
  1196. return;
  1197. }
  1198. val = exp.X_add_number;
  1199. if (val < 0 || val > 7)
  1200. rl78_error (_("rtsd size must be 0..7"));
  1201. }
  1202. static int
  1203. exp_val (expressionS exp)
  1204. {
  1205. if (exp.X_op != O_constant)
  1206. {
  1207. rl78_error (_("constant expected"));
  1208. return 0;
  1209. }
  1210. return exp.X_add_number;
  1211. }
  1212. static int
  1213. check_expr_is_const (expressionS e, int vmin, int vmax)
  1214. {
  1215. static char buf[100];
  1216. if (e.X_op != O_constant
  1217. || e.X_add_number < vmin
  1218. || e.X_add_number > vmax)
  1219. {
  1220. if (vmin == vmax)
  1221. sprintf (buf, "%d expected here", vmin);
  1222. else
  1223. sprintf (buf, "%d..%d expected here", vmin, vmax);
  1224. rl78_error(buf);
  1225. return 0;
  1226. }
  1227. return 1;
  1228. }