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