1 /* rx-parse.y Renesas RX parser 2 Copyright (C) 2008-2016 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 %{ 21 22 #include "as.h" 23 #include "safe-ctype.h" 24 #include "rx-defs.h" 25 26 static int rx_lex (void); 27 28 #define COND_EQ 0 29 #define COND_NE 1 30 31 #define MEMEX 0x06 32 33 #define BSIZE 0 34 #define WSIZE 1 35 #define LSIZE 2 36 37 /* .sb .sw .l .uw */ 38 static int sizemap[] = { BSIZE, WSIZE, LSIZE, WSIZE }; 39 40 /* Ok, here are the rules for using these macros... 41 42 B*() is used to specify the base opcode bytes. Fields to be filled 43 in later, leave zero. Call this first. 44 45 F() and FE() are used to fill in fields within the base opcode bytes. You MUST 46 call B*() before any F() or FE(). 47 48 [UN]*O*(), PC*() appends operands to the end of the opcode. You 49 must call P() and B*() before any of these, so that the fixups 50 have the right byte location. 51 O = signed, UO = unsigned, NO = negated, PC = pcrel 52 53 IMM() adds an immediate and fills in the field for it. 54 NIMM() same, but negates the immediate. 55 NBIMM() same, but negates the immediate, for sbb. 56 DSP() adds a displacement, and fills in the field for it. 57 58 Note that order is significant for the O, IMM, and DSP macros, as 59 they append their data to the operand buffer in the order that you 60 call them. 61 62 Use "disp" for displacements whenever possible; this handles the 63 "0" case properly. */ 64 65 #define B1(b1) rx_base1 (b1) 66 #define B2(b1, b2) rx_base2 (b1, b2) 67 #define B3(b1, b2, b3) rx_base3 (b1, b2, b3) 68 #define B4(b1, b2, b3, b4) rx_base4 (b1, b2, b3, b4) 69 70 /* POS is bits from the MSB of the first byte to the LSB of the last byte. */ 71 #define F(val,pos,sz) rx_field (val, pos, sz) 72 #define FE(exp,pos,sz) rx_field (exp_val (exp), pos, sz); 73 74 #define O1(v) rx_op (v, 1, RXREL_SIGNED); rx_range (v, -128, 255) 75 #define O2(v) rx_op (v, 2, RXREL_SIGNED); rx_range (v, -32768, 65536) 76 #define O3(v) rx_op (v, 3, RXREL_SIGNED); rx_range (v, -8388608, 16777216) 77 #define O4(v) rx_op (v, 4, RXREL_SIGNED) 78 79 #define UO1(v) rx_op (v, 1, RXREL_UNSIGNED); rx_range (v, 0, 255) 80 #define UO2(v) rx_op (v, 2, RXREL_UNSIGNED); rx_range (v, 0, 65536) 81 #define UO3(v) rx_op (v, 3, RXREL_UNSIGNED); rx_range (v, 0, 16777216) 82 #define UO4(v) rx_op (v, 4, RXREL_UNSIGNED) 83 84 #define NO1(v) rx_op (v, 1, RXREL_NEGATIVE) 85 #define NO2(v) rx_op (v, 2, RXREL_NEGATIVE) 86 #define NO3(v) rx_op (v, 3, RXREL_NEGATIVE) 87 #define NO4(v) rx_op (v, 4, RXREL_NEGATIVE) 88 89 #define PC1(v) rx_op (v, 1, RXREL_PCREL) 90 #define PC2(v) rx_op (v, 2, RXREL_PCREL) 91 #define PC3(v) rx_op (v, 3, RXREL_PCREL) 92 93 #define IMM_(v,pos,size) F (immediate (v, RXREL_SIGNED, pos, size), pos, 2); \ 94 if (v.X_op != O_constant && v.X_op != O_big) rx_linkrelax_imm (pos) 95 #define IMM(v,pos) IMM_ (v, pos, 32) 96 #define IMMW(v,pos) IMM_ (v, pos, 16); rx_range (v, -32768, 65536) 97 #define IMMB(v,pos) IMM_ (v, pos, 8); rx_range (v, -128, 255) 98 #define NIMM(v,pos) F (immediate (v, RXREL_NEGATIVE, pos, 32), pos, 2) 99 #define NBIMM(v,pos) F (immediate (v, RXREL_NEGATIVE_BORROW, pos, 32), pos, 2) 100 #define DSP(v,pos,msz) if (!v.X_md) rx_relax (RX_RELAX_DISP, pos); \ 101 else rx_linkrelax_dsp (pos); \ 102 F (displacement (v, msz), pos, 2) 103 104 #define id24(a,b2,b3) B3 (0xfb + a, b2, b3) 105 106 static void rx_check_float_support (void); 107 static int rx_intop (expressionS, int, int); 108 static int rx_uintop (expressionS, int); 109 static int rx_disp3op (expressionS); 110 static int rx_disp5op (expressionS *, int); 111 static int rx_disp5op0 (expressionS *, int); 112 static int exp_val (expressionS exp); 113 static expressionS zero_expr (void); 114 static int immediate (expressionS, int, int, int); 115 static int displacement (expressionS, int); 116 static void rtsd_immediate (expressionS); 117 static void rx_range (expressionS, int, int); 118 static void rx_check_v2 (void); 119 120 static int need_flag = 0; 121 static int rx_in_brackets = 0; 122 static int rx_last_token = 0; 123 static char * rx_init_start; 124 static char * rx_last_exp_start = 0; 125 static int sub_op; 126 static int sub_op2; 127 128 #define YYDEBUG 1 129 #define YYERROR_VERBOSE 1 130 131 %} 132 133 %name-prefix="rx_" 134 135 %union { 136 int regno; 137 expressionS exp; 138 } 139 140 %type <regno> REG FLAG CREG BCND BMCND SCCND ACC 141 %type <regno> flag bwl bw memex 142 %type <exp> EXPR disp 143 144 %token REG FLAG CREG ACC 145 146 %token EXPR UNKNOWN_OPCODE IS_OPCODE 147 148 %token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW 149 150 %token ABS ADC ADD AND_ 151 %token BCLR BCND BMCND BNOT BRA BRK BSET BSR BTST 152 %token CLRPSW CMP 153 %token DBT DIV DIVU 154 %token EDIV EDIVU EMACA EMSBA EMUL EMULA EMULU 155 %token FADD FCMP FDIV FMUL FREIT FSUB FSQRT FTOI FTOU 156 %token INT ITOF 157 %token JMP JSR 158 %token MACHI MACLH MACLO MAX MIN MOV MOVCO MOVLI MOVU MSBHI MSBLH MSBLO MUL 159 %token MULHI MULLH MULLO MULU MVFACHI MVFACGU MVFACMI MVFACLO MVFC MVTACGU 160 %token MVTACHI MVTACLO MVTC MVTIPL 161 %token NEG NOP NOT 162 %token OR 163 %token POP POPC POPM PUSH PUSHA PUSHC PUSHM 164 %token RACL RACW RDACL RDACW REIT REVL REVW RMPA ROLC RORC ROTL ROTR ROUND 165 %token RTE RTFI RTS RTSD 166 %token SAT SATR SBB SCCND SCMPU SETPSW SHAR SHLL SHLR SMOVB SMOVF 167 %token SMOVU SSTR STNZ STOP STZ SUB SUNTIL SWHILE 168 %token TST 169 %token UTOF 170 %token WAIT 171 %token XCHG XOR 172 173 %% 174 /* ====================================================================== */ 175 176 statement : 177 178 UNKNOWN_OPCODE 179 { as_bad (_("Unknown opcode: %s"), rx_init_start); } 180 181 /* ---------------------------------------------------------------------- */ 182 183 | BRK 184 { B1 (0x00); } 185 186 | DBT 187 { B1 (0x01); } 188 189 | RTS 190 { B1 (0x02); } 191 192 | NOP 193 { B1 (0x03); } 194 195 /* ---------------------------------------------------------------------- */ 196 197 | BRA EXPR 198 { if (rx_disp3op ($2)) 199 { B1 (0x08); rx_disp3 ($2, 5); } 200 else if (rx_intop ($2, 8, 8)) 201 { B1 (0x2e); PC1 ($2); } 202 else if (rx_intop ($2, 16, 16)) 203 { B1 (0x38); PC2 ($2); } 204 else if (rx_intop ($2, 24, 24)) 205 { B1 (0x04); PC3 ($2); } 206 else 207 { rx_relax (RX_RELAX_BRANCH, 0); 208 rx_linkrelax_branch (); 209 /* We'll convert this to a longer one later if needed. */ 210 B1 (0x08); rx_disp3 ($2, 5); } } 211 212 | BRA DOT_A EXPR 213 { B1 (0x04); PC3 ($3); } 214 215 | BRA DOT_S EXPR 216 { B1 (0x08); rx_disp3 ($3, 5); } 217 218 /* ---------------------------------------------------------------------- */ 219 220 | BSR EXPR 221 { if (rx_intop ($2, 16, 16)) 222 { B1 (0x39); PC2 ($2); } 223 else if (rx_intop ($2, 24, 24)) 224 { B1 (0x05); PC3 ($2); } 225 else 226 { rx_relax (RX_RELAX_BRANCH, 0); 227 rx_linkrelax_branch (); 228 B1 (0x39); PC2 ($2); } } 229 | BSR DOT_A EXPR 230 { B1 (0x05), PC3 ($3); } 231 232 /* ---------------------------------------------------------------------- */ 233 234 | BCND DOT_S EXPR 235 { if ($1 == COND_EQ || $1 == COND_NE) 236 { B1 ($1 == COND_EQ ? 0x10 : 0x18); rx_disp3 ($3, 5); } 237 else 238 as_bad (_("Only BEQ and BNE may have .S")); } 239 240 /* ---------------------------------------------------------------------- */ 241 242 | BCND DOT_B EXPR 243 { B1 (0x20); F ($1, 4, 4); PC1 ($3); } 244 245 | BRA DOT_B EXPR 246 { B1 (0x2e), PC1 ($3); } 247 248 /* ---------------------------------------------------------------------- */ 249 250 | BRA DOT_W EXPR 251 { B1 (0x38), PC2 ($3); } 252 | BSR DOT_W EXPR 253 { B1 (0x39), PC2 ($3); } 254 | BCND DOT_W EXPR 255 { if ($1 == COND_EQ || $1 == COND_NE) 256 { B1 ($1 == COND_EQ ? 0x3a : 0x3b); PC2 ($3); } 257 else 258 as_bad (_("Only BEQ and BNE may have .W")); } 259 | BCND EXPR 260 { if ($1 == COND_EQ || $1 == COND_NE) 261 { 262 rx_relax (RX_RELAX_BRANCH, 0); 263 rx_linkrelax_branch (); 264 B1 ($1 == COND_EQ ? 0x10 : 0x18); rx_disp3 ($2, 5); 265 } 266 else 267 { 268 rx_relax (RX_RELAX_BRANCH, 0); 269 /* This is because we might turn it into a 270 jump-over-jump long branch. */ 271 rx_linkrelax_branch (); 272 B1 (0x20); F ($1, 4, 4); PC1 ($2); 273 } } 274 275 /* ---------------------------------------------------------------------- */ 276 277 | MOV DOT_B '#' EXPR ',' '[' REG ']' 278 { B2 (0xf8, 0x04); F ($7, 8, 4); IMMB ($4, 12);} 279 280 | MOV DOT_W '#' EXPR ',' '[' REG ']' 281 { B2 (0xf8, 0x01); F ($7, 8, 4); IMMW ($4, 12);} 282 283 | MOV DOT_L '#' EXPR ',' '[' REG ']' 284 { B2 (0xf8, 0x02); F ($7, 8, 4); IMM ($4, 12);} 285 286 | MOV DOT_B '#' EXPR ',' disp '[' REG ']' 287 /* rx_disp5op changes the value if it succeeds, so keep it last. */ 288 { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, BSIZE)) 289 { B2 (0x3c, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); } 290 else 291 { B2 (0xf8, 0x04); F ($8, 8, 4); DSP ($6, 6, BSIZE); O1 ($4); 292 if ($4.X_op != O_constant && $4.X_op != O_big) rx_linkrelax_imm (12); } } 293 294 | MOV DOT_W '#' EXPR ',' disp '[' REG ']' 295 { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, WSIZE)) 296 { B2 (0x3d, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); } 297 else 298 { B2 (0xf8, 0x01); F ($8, 8, 4); DSP ($6, 6, WSIZE); IMMW ($4, 12); } } 299 300 | MOV DOT_L '#' EXPR ',' disp '[' REG ']' 301 { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, LSIZE)) 302 { B2 (0x3e, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); } 303 else 304 { B2 (0xf8, 0x02); F ($8, 8, 4); DSP ($6, 6, LSIZE); IMM ($4, 12); } } 305 306 /* ---------------------------------------------------------------------- */ 307 308 | RTSD '#' EXPR ',' REG '-' REG 309 { B2 (0x3f, 0); F ($5, 8, 4); F ($7, 12, 4); rtsd_immediate ($3); 310 if ($5 == 0) 311 rx_error (_("RTSD cannot pop R0")); 312 if ($5 > $7) 313 rx_error (_("RTSD first reg must be <= second reg")); } 314 315 /* ---------------------------------------------------------------------- */ 316 317 | CMP REG ',' REG 318 { B2 (0x47, 0); F ($2, 8, 4); F ($4, 12, 4); } 319 320 /* ---------------------------------------------------------------------- */ 321 322 | CMP disp '[' REG ']' DOT_UB ',' REG 323 { B2 (0x44, 0); F ($4, 8, 4); F ($8, 12, 4); DSP ($2, 6, BSIZE); } 324 325 | CMP disp '[' REG ']' memex ',' REG 326 { B3 (MEMEX, 0x04, 0); F ($6, 8, 2); F ($4, 16, 4); F ($8, 20, 4); DSP ($2, 14, sizemap[$6]); } 327 328 /* ---------------------------------------------------------------------- */ 329 330 | MOVU bw REG ',' REG 331 { B2 (0x5b, 0x00); F ($2, 5, 1); F ($3, 8, 4); F ($5, 12, 4); } 332 333 /* ---------------------------------------------------------------------- */ 334 335 | MOVU bw '[' REG ']' ',' REG 336 { B2 (0x58, 0x00); F ($2, 5, 1); F ($4, 8, 4); F ($7, 12, 4); } 337 338 | MOVU bw EXPR '[' REG ']' ',' REG 339 { if ($5 <= 7 && $8 <= 7 && rx_disp5op (&$3, $2)) 340 { B2 (0xb0, 0); F ($2, 4, 1); F ($5, 9, 3); F ($8, 13, 3); rx_field5s ($3); } 341 else 342 { B2 (0x58, 0x00); F ($2, 5, 1); F ($5, 8, 4); F ($8, 12, 4); DSP ($3, 6, $2); } } 343 344 /* ---------------------------------------------------------------------- */ 345 346 | SUB '#' EXPR ',' REG 347 { if (rx_uintop ($3, 4)) 348 { B2 (0x60, 0); FE ($3, 8, 4); F ($5, 12, 4); } 349 else 350 /* This is really an add, but we negate the immediate. */ 351 { B2 (0x70, 0); F ($5, 8, 4); F ($5, 12, 4); NIMM ($3, 6); } } 352 353 | CMP '#' EXPR ',' REG 354 { if (rx_uintop ($3, 4)) 355 { B2 (0x61, 0); FE ($3, 8, 4); F ($5, 12, 4); } 356 else if (rx_uintop ($3, 8)) 357 { B2 (0x75, 0x50); F ($5, 12, 4); UO1 ($3); } 358 else 359 { B2 (0x74, 0x00); F ($5, 12, 4); IMM ($3, 6); } } 360 361 | ADD '#' EXPR ',' REG 362 { if (rx_uintop ($3, 4)) 363 { B2 (0x62, 0); FE ($3, 8, 4); F ($5, 12, 4); } 364 else 365 { B2 (0x70, 0); F ($5, 8, 4); F ($5, 12, 4); IMM ($3, 6); } } 366 367 | MUL '#' EXPR ',' REG 368 { if (rx_uintop ($3, 4)) 369 { B2 (0x63, 0); FE ($3, 8, 4); F ($5, 12, 4); } 370 else 371 { B2 (0x74, 0x10); F ($5, 12, 4); IMM ($3, 6); } } 372 373 | AND_ '#' EXPR ',' REG 374 { if (rx_uintop ($3, 4)) 375 { B2 (0x64, 0); FE ($3, 8, 4); F ($5, 12, 4); } 376 else 377 { B2 (0x74, 0x20); F ($5, 12, 4); IMM ($3, 6); } } 378 379 | OR '#' EXPR ',' REG 380 { if (rx_uintop ($3, 4)) 381 { B2 (0x65, 0); FE ($3, 8, 4); F ($5, 12, 4); } 382 else 383 { B2 (0x74, 0x30); F ($5, 12, 4); IMM ($3, 6); } } 384 385 | MOV DOT_L '#' EXPR ',' REG 386 { if (rx_uintop ($4, 4)) 387 { B2 (0x66, 0); FE ($4, 8, 4); F ($6, 12, 4); } 388 else if (rx_uintop ($4, 8)) 389 { B2 (0x75, 0x40); F ($6, 12, 4); UO1 ($4); } 390 else 391 { B2 (0xfb, 0x02); F ($6, 8, 4); IMM ($4, 12); } } 392 393 | MOV '#' EXPR ',' REG 394 { if (rx_uintop ($3, 4)) 395 { B2 (0x66, 0); FE ($3, 8, 4); F ($5, 12, 4); } 396 else if (rx_uintop ($3, 8)) 397 { B2 (0x75, 0x40); F ($5, 12, 4); UO1 ($3); } 398 else 399 { B2 (0xfb, 0x02); F ($5, 8, 4); IMM ($3, 12); } } 400 401 /* ---------------------------------------------------------------------- */ 402 403 | RTSD '#' EXPR 404 { B1 (0x67); rtsd_immediate ($3); } 405 406 /* ---------------------------------------------------------------------- */ 407 408 | SHLR { sub_op = 0; } op_shift 409 | SHAR { sub_op = 1; } op_shift 410 | SHLL { sub_op = 2; } op_shift 411 412 /* ---------------------------------------------------------------------- */ 413 414 | PUSHM REG '-' REG 415 { 416 if ($2 == $4) 417 { B2 (0x7e, 0x80); F (LSIZE, 10, 2); F ($2, 12, 4); } 418 else 419 { B2 (0x6e, 0); F ($2, 8, 4); F ($4, 12, 4); } 420 if ($2 == 0) 421 rx_error (_("PUSHM cannot push R0")); 422 if ($2 > $4) 423 rx_error (_("PUSHM first reg must be <= second reg")); } 424 425 /* ---------------------------------------------------------------------- */ 426 427 | POPM REG '-' REG 428 { 429 if ($2 == $4) 430 { B2 (0x7e, 0xb0); F ($2, 12, 4); } 431 else 432 { B2 (0x6f, 0); F ($2, 8, 4); F ($4, 12, 4); } 433 if ($2 == 0) 434 rx_error (_("POPM cannot pop R0")); 435 if ($2 > $4) 436 rx_error (_("POPM first reg must be <= second reg")); } 437 438 /* ---------------------------------------------------------------------- */ 439 440 | ADD '#' EXPR ',' REG ',' REG 441 { B2 (0x70, 0x00); F ($5, 8, 4); F ($7, 12, 4); IMM ($3, 6); } 442 443 /* ---------------------------------------------------------------------- */ 444 445 | INT '#' EXPR 446 { B2(0x75, 0x60), UO1 ($3); } 447 448 /* ---------------------------------------------------------------------- */ 449 450 | BSET '#' EXPR ',' REG 451 { B2 (0x78, 0); FE ($3, 7, 5); F ($5, 12, 4); } 452 | BCLR '#' EXPR ',' REG 453 { B2 (0x7a, 0); FE ($3, 7, 5); F ($5, 12, 4); } 454 455 /* ---------------------------------------------------------------------- */ 456 457 | BTST '#' EXPR ',' REG 458 { B2 (0x7c, 0x00); FE ($3, 7, 5); F ($5, 12, 4); } 459 460 /* ---------------------------------------------------------------------- */ 461 462 | SAT REG 463 { B2 (0x7e, 0x30); F ($2, 12, 4); } 464 | RORC REG 465 { B2 (0x7e, 0x40); F ($2, 12, 4); } 466 | ROLC REG 467 { B2 (0x7e, 0x50); F ($2, 12, 4); } 468 469 /* ---------------------------------------------------------------------- */ 470 471 | PUSH bwl REG 472 { B2 (0x7e, 0x80); F ($2, 10, 2); F ($3, 12, 4); } 473 474 /* ---------------------------------------------------------------------- */ 475 476 | POP REG 477 { B2 (0x7e, 0xb0); F ($2, 12, 4); } 478 479 /* ---------------------------------------------------------------------- */ 480 481 | PUSHC CREG 482 { if ($2 == 13) 483 { rx_check_v2 (); } 484 if ($2 < 16) 485 { B2 (0x7e, 0xc0); F ($2, 12, 4); } 486 else 487 as_bad (_("PUSHC can only push the first 16 control registers")); } 488 489 /* ---------------------------------------------------------------------- */ 490 491 | POPC CREG 492 { if ($2 == 13) 493 { rx_check_v2 (); } 494 if ($2 < 16) 495 { B2 (0x7e, 0xe0); F ($2, 12, 4); } 496 else 497 as_bad (_("POPC can only pop the first 16 control registers")); } 498 499 /* ---------------------------------------------------------------------- */ 500 501 | SETPSW flag 502 { B2 (0x7f, 0xa0); F ($2, 12, 4); } 503 | CLRPSW flag 504 { B2 (0x7f, 0xb0); F ($2, 12, 4); } 505 506 /* ---------------------------------------------------------------------- */ 507 508 | JMP REG 509 { B2 (0x7f, 0x00); F ($2, 12, 4); } 510 | JSR REG 511 { B2 (0x7f, 0x10); F ($2, 12, 4); } 512 | BRA opt_l REG 513 { B2 (0x7f, 0x40); F ($3, 12, 4); } 514 | BSR opt_l REG 515 { B2 (0x7f, 0x50); F ($3, 12, 4); } 516 517 /* ---------------------------------------------------------------------- */ 518 519 | SCMPU 520 { B2 (0x7f, 0x83); rx_note_string_insn_use (); } 521 | SMOVU 522 { B2 (0x7f, 0x87); rx_note_string_insn_use (); } 523 | SMOVB 524 { B2 (0x7f, 0x8b); rx_note_string_insn_use (); } 525 | SMOVF 526 { B2 (0x7f, 0x8f); rx_note_string_insn_use (); } 527 528 /* ---------------------------------------------------------------------- */ 529 530 | SUNTIL bwl 531 { B2 (0x7f, 0x80); F ($2, 14, 2); rx_note_string_insn_use (); } 532 | SWHILE bwl 533 { B2 (0x7f, 0x84); F ($2, 14, 2); rx_note_string_insn_use (); } 534 | SSTR bwl 535 { B2 (0x7f, 0x88); F ($2, 14, 2); } 536 537 /* ---------------------------------------------------------------------- */ 538 539 | RMPA bwl 540 { B2 (0x7f, 0x8c); F ($2, 14, 2); rx_note_string_insn_use (); } 541 542 /* ---------------------------------------------------------------------- */ 543 544 | RTFI 545 { B2 (0x7f, 0x94); } 546 | RTE 547 { B2 (0x7f, 0x95); } 548 | WAIT 549 { B2 (0x7f, 0x96); } 550 | SATR 551 { B2 (0x7f, 0x93); } 552 553 /* ---------------------------------------------------------------------- */ 554 555 | MVTIPL '#' EXPR 556 { B3 (0x75, 0x70, 0x00); FE ($3, 20, 4); } 557 558 /* ---------------------------------------------------------------------- */ 559 560 /* rx_disp5op changes the value if it succeeds, so keep it last. */ 561 | MOV bwl REG ',' EXPR '[' REG ']' 562 { if ($3 <= 7 && $7 <= 7 && rx_disp5op (&$5, $2)) 563 { B2 (0x80, 0); F ($2, 2, 2); F ($7, 9, 3); F ($3, 13, 3); rx_field5s ($5); } 564 else 565 { B2 (0xc3, 0x00); F ($2, 2, 2); F ($7, 8, 4); F ($3, 12, 4); DSP ($5, 4, $2); }} 566 567 /* ---------------------------------------------------------------------- */ 568 569 | MOV bwl EXPR '[' REG ']' ',' REG 570 { if ($5 <= 7 && $8 <= 7 && rx_disp5op (&$3, $2)) 571 { B2 (0x88, 0); F ($2, 2, 2); F ($5, 9, 3); F ($8, 13, 3); rx_field5s ($3); } 572 else 573 { B2 (0xcc, 0x00); F ($2, 2, 2); F ($5, 8, 4); F ($8, 12, 4); DSP ($3, 6, $2); } } 574 575 /* ---------------------------------------------------------------------- */ 576 577 /* MOV a,b - if a is a reg and b is mem, src and dest are 578 swapped. */ 579 580 /* We don't use "disp" here because it causes a shift/reduce 581 conflict with the other displacement-less patterns. */ 582 583 | MOV bwl REG ',' '[' REG ']' 584 { B2 (0xc3, 0x00); F ($2, 2, 2); F ($6, 8, 4); F ($3, 12, 4); } 585 586 /* ---------------------------------------------------------------------- */ 587 588 | MOV bwl '[' REG ']' ',' disp '[' REG ']' 589 { B2 (0xc0, 0); F ($2, 2, 2); F ($4, 8, 4); F ($9, 12, 4); DSP ($7, 4, $2); } 590 591 /* ---------------------------------------------------------------------- */ 592 593 | MOV bwl EXPR '[' REG ']' ',' disp '[' REG ']' 594 { B2 (0xc0, 0x00); F ($2, 2, 2); F ($5, 8, 4); F ($10, 12, 4); DSP ($3, 6, $2); DSP ($8, 4, $2); } 595 596 /* ---------------------------------------------------------------------- */ 597 598 | MOV bwl REG ',' REG 599 { B2 (0xcf, 0x00); F ($2, 2, 2); F ($3, 8, 4); F ($5, 12, 4); } 600 601 /* ---------------------------------------------------------------------- */ 602 603 | MOV bwl '[' REG ']' ',' REG 604 { B2 (0xcc, 0x00); F ($2, 2, 2); F ($4, 8, 4); F ($7, 12, 4); } 605 606 /* ---------------------------------------------------------------------- */ 607 608 | BSET '#' EXPR ',' disp '[' REG ']' DOT_B 609 { B2 (0xf0, 0x00); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); } 610 | BCLR '#' EXPR ',' disp '[' REG ']' DOT_B 611 { B2 (0xf0, 0x08); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); } 612 | BTST '#' EXPR ',' disp '[' REG ']' DOT_B 613 { B2 (0xf4, 0x00); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); } 614 615 /* ---------------------------------------------------------------------- */ 616 617 | PUSH bwl disp '[' REG ']' 618 { B2 (0xf4, 0x08); F ($2, 14, 2); F ($5, 8, 4); DSP ($3, 6, $2); } 619 620 /* ---------------------------------------------------------------------- */ 621 622 | SBB { sub_op = 0; } op_dp20_rm_l 623 | NEG { sub_op = 1; sub_op2 = 1; } op_dp20_rr 624 | ADC { sub_op = 2; } op_dp20_rim_l 625 | ABS { sub_op = 3; sub_op2 = 2; } op_dp20_rr 626 | MAX { sub_op = 4; } op_dp20_rim 627 | MIN { sub_op = 5; } op_dp20_rim 628 | EMUL { sub_op = 6; } op_dp20_i 629 | EMULU { sub_op = 7; } op_dp20_i 630 | DIV { sub_op = 8; } op_dp20_rim 631 | DIVU { sub_op = 9; } op_dp20_rim 632 | TST { sub_op = 12; } op_dp20_rim 633 | XOR { sub_op = 13; } op_dp20_rim 634 | NOT { sub_op = 14; sub_op2 = 0; } op_dp20_rr 635 | STZ { sub_op = 14; sub_op2 = 0; } op_dp20_ri 636 | STNZ { sub_op = 15; sub_op2 = 1; } op_dp20_ri 637 638 /* ---------------------------------------------------------------------- */ 639 640 | EMUL { sub_op = 6; } op_xchg 641 | EMULU { sub_op = 7; } op_xchg 642 | XCHG { sub_op = 16; } op_xchg 643 | ITOF { sub_op = 17; } op_xchg 644 | UTOF { sub_op = 21; } op_xchg 645 646 /* ---------------------------------------------------------------------- */ 647 648 | BSET REG ',' REG 649 { id24 (1, 0x63, 0x00); F ($4, 16, 4); F ($2, 20, 4); } 650 | BCLR REG ',' REG 651 { id24 (1, 0x67, 0x00); F ($4, 16, 4); F ($2, 20, 4); } 652 | BTST REG ',' REG 653 { id24 (1, 0x6b, 0x00); F ($4, 16, 4); F ($2, 20, 4); } 654 | BNOT REG ',' REG 655 { id24 (1, 0x6f, 0x00); F ($4, 16, 4); F ($2, 20, 4); } 656 657 | BSET REG ',' disp '[' REG ']' opt_b 658 { id24 (1, 0x60, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); } 659 | BCLR REG ',' disp '[' REG ']' opt_b 660 { id24 (1, 0x64, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); } 661 | BTST REG ',' disp '[' REG ']' opt_b 662 { id24 (1, 0x68, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); } 663 | BNOT REG ',' disp '[' REG ']' opt_b 664 { id24 (1, 0x6c, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); } 665 666 /* ---------------------------------------------------------------------- */ 667 668 | FSUB { sub_op = 0; } float3_op 669 | FCMP { sub_op = 1; } float2_op 670 | FADD { sub_op = 2; } float3_op 671 | FMUL { sub_op = 3; } float3_op 672 | FDIV { sub_op = 4; } float2_op 673 | FSQRT { sub_op = 8; } float2_op_ni 674 | FTOI { sub_op = 5; } float2_op_ni 675 | FTOU { sub_op = 9; } float2_op_ni 676 | ROUND { sub_op = 6; } float2_op_ni 677 678 /* ---------------------------------------------------------------------- */ 679 680 681 /* ---------------------------------------------------------------------- */ 682 683 | SCCND DOT_L REG 684 { id24 (1, 0xdb, 0x00); F ($1, 20, 4); F ($3, 16, 4); } 685 | SCCND bwl disp '[' REG ']' 686 { id24 (1, 0xd0, 0x00); F ($1, 20, 4); F ($2, 12, 2); F ($5, 16, 4); DSP ($3, 14, $2); } 687 688 /* ---------------------------------------------------------------------- */ 689 690 | BMCND '#' EXPR ',' disp '[' REG ']' opt_b 691 { id24 (1, 0xe0, 0x00); F ($1, 20, 4); FE ($3, 11, 3); 692 F ($7, 16, 4); DSP ($5, 14, BSIZE); } 693 694 /* ---------------------------------------------------------------------- */ 695 696 | BNOT '#' EXPR ',' disp '[' REG ']' opt_b 697 { id24 (1, 0xe0, 0x0f); FE ($3, 11, 3); F ($7, 16, 4); 698 DSP ($5, 14, BSIZE); } 699 700 /* ---------------------------------------------------------------------- */ 701 702 | MULHI REG ',' REG 703 { id24 (2, 0x00, 0x00); F ($2, 16, 4); F ($4, 20, 4); } 704 | MULHI REG ',' REG ',' ACC 705 { rx_check_v2 (); id24 (2, 0x00, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 706 | MULLO REG ',' REG 707 { id24 (2, 0x01, 0x00); F ($2, 16, 4); F ($4, 20, 4); } 708 | MULLO REG ',' REG ',' ACC 709 { rx_check_v2 (); id24 (2, 0x01, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 710 | MACHI REG ',' REG 711 { id24 (2, 0x04, 0x00); F ($2, 16, 4); F ($4, 20, 4); } 712 | MACHI REG ',' REG ',' ACC 713 { rx_check_v2 (); id24 (2, 0x04, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 714 | MACLO REG ',' REG 715 { id24 (2, 0x05, 0x00); F ($2, 16, 4); F ($4, 20, 4); } 716 | MACLO REG ',' REG ',' ACC 717 { rx_check_v2 (); id24 (2, 0x05, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 718 719 /* ---------------------------------------------------------------------- */ 720 721 /* We don't have syntax for these yet. */ 722 | MVTACHI REG 723 { id24 (2, 0x17, 0x00); F ($2, 20, 4); } 724 | MVTACHI REG ',' ACC 725 { rx_check_v2 (); id24 (2, 0x17, 0x00); F ($2, 20, 4); F ($4, 16, 1); } 726 | MVTACLO REG 727 { id24 (2, 0x17, 0x10); F ($2, 20, 4); } 728 | MVTACLO REG ',' ACC 729 { rx_check_v2 (); id24 (2, 0x17, 0x10); F ($2, 20, 4); F ($4, 16, 1); } 730 | MVFACHI REG 731 { id24 (2, 0x1f, 0x00); F ($2, 20, 4); } 732 | MVFACHI { sub_op = 0; } mvfa_op 733 | MVFACMI REG 734 { id24 (2, 0x1f, 0x20); F ($2, 20, 4); } 735 | MVFACMI { sub_op = 2; } mvfa_op 736 | MVFACLO REG 737 { id24 (2, 0x1f, 0x10); F ($2, 20, 4); } 738 | MVFACLO { sub_op = 1; } mvfa_op 739 | RACW '#' EXPR 740 { id24 (2, 0x18, 0x00); 741 if (rx_uintop ($3, 4) && $3.X_add_number == 1) 742 ; 743 else if (rx_uintop ($3, 4) && $3.X_add_number == 2) 744 F (1, 19, 1); 745 else 746 as_bad (_("RACW expects #1 or #2"));} 747 | RACW '#' EXPR ',' ACC 748 { rx_check_v2 (); id24 (2, 0x18, 0x00); F ($5, 16, 1); 749 if (rx_uintop ($3, 4) && $3.X_add_number == 1) 750 ; 751 else if (rx_uintop ($3, 4) && $3.X_add_number == 2) 752 F (1, 19, 1); 753 else 754 as_bad (_("RACW expects #1 or #2"));} 755 756 /* ---------------------------------------------------------------------- */ 757 758 | MOV bwl REG ',' '[' REG '+' ']' 759 { id24 (2, 0x20, 0); F ($2, 14, 2); F ($6, 16, 4); F ($3, 20, 4); } 760 | MOV bwl REG ',' '[' '-' REG ']' 761 { id24 (2, 0x24, 0); F ($2, 14, 2); F ($7, 16, 4); F ($3, 20, 4); } 762 763 /* ---------------------------------------------------------------------- */ 764 765 | MOV bwl '[' REG '+' ']' ',' REG 766 { id24 (2, 0x28, 0); F ($2, 14, 2); F ($4, 16, 4); F ($8, 20, 4); } 767 | MOV bwl '[' '-' REG ']' ',' REG 768 { id24 (2, 0x2c, 0); F ($2, 14, 2); F ($5, 16, 4); F ($8, 20, 4); } 769 770 /* ---------------------------------------------------------------------- */ 771 772 | MOVU bw '[' REG '+' ']' ',' REG 773 { id24 (2, 0x38, 0); F ($2, 15, 1); F ($4, 16, 4); F ($8, 20, 4); } 774 | MOVU bw '[' '-' REG ']' ',' REG 775 { id24 (2, 0x3c, 0); F ($2, 15, 1); F ($5, 16, 4); F ($8, 20, 4); } 776 777 /* ---------------------------------------------------------------------- */ 778 779 | ROTL { sub_op = 6; } op_shift_rot 780 | ROTR { sub_op = 4; } op_shift_rot 781 | REVW { sub_op = 5; } op_shift_rot 782 | REVL { sub_op = 7; } op_shift_rot 783 784 /* ---------------------------------------------------------------------- */ 785 786 | MVTC REG ',' CREG 787 { if ($4 == 13) 788 rx_check_v2 (); 789 id24 (2, 0x68, 0x00); F ($4 % 16, 20, 4); F ($4 / 16, 15, 1); 790 F ($2, 16, 4); } 791 792 /* ---------------------------------------------------------------------- */ 793 794 | MVFC CREG ',' REG 795 { if ($2 == 13) 796 rx_check_v2 (); 797 id24 (2, 0x6a, 0); F ($2, 15, 5); F ($4, 20, 4); } 798 799 /* ---------------------------------------------------------------------- */ 800 801 | ROTL '#' EXPR ',' REG 802 { id24 (2, 0x6e, 0); FE ($3, 15, 5); F ($5, 20, 4); } 803 | ROTR '#' EXPR ',' REG 804 { id24 (2, 0x6c, 0); FE ($3, 15, 5); F ($5, 20, 4); } 805 806 /* ---------------------------------------------------------------------- */ 807 808 | MVTC '#' EXPR ',' CREG 809 { if ($5 == 13) 810 rx_check_v2 (); 811 id24 (2, 0x73, 0x00); F ($5, 19, 5); IMM ($3, 12); } 812 813 /* ---------------------------------------------------------------------- */ 814 815 | BMCND '#' EXPR ',' REG 816 { id24 (2, 0xe0, 0x00); F ($1, 16, 4); FE ($3, 11, 5); 817 F ($5, 20, 4); } 818 819 /* ---------------------------------------------------------------------- */ 820 821 | BNOT '#' EXPR ',' REG 822 { id24 (2, 0xe0, 0xf0); FE ($3, 11, 5); F ($5, 20, 4); } 823 824 /* ---------------------------------------------------------------------- */ 825 826 | MOV bwl REG ',' '[' REG ',' REG ']' 827 { id24 (3, 0x00, 0); F ($2, 10, 2); F ($6, 12, 4); F ($8, 16, 4); F ($3, 20, 4); } 828 829 | MOV bwl '[' REG ',' REG ']' ',' REG 830 { id24 (3, 0x40, 0); F ($2, 10, 2); F ($4, 12, 4); F ($6, 16, 4); F ($9, 20, 4); } 831 832 | MOVU bw '[' REG ',' REG ']' ',' REG 833 { id24 (3, 0xc0, 0); F ($2, 10, 2); F ($4, 12, 4); F ($6, 16, 4); F ($9, 20, 4); } 834 835 /* ---------------------------------------------------------------------- */ 836 837 | SUB { sub_op = 0; } op_subadd 838 | ADD { sub_op = 2; } op_subadd 839 | MUL { sub_op = 3; } op_subadd 840 | AND_ { sub_op = 4; } op_subadd 841 | OR { sub_op = 5; } op_subadd 842 843 /* ---------------------------------------------------------------------- */ 844 /* There is no SBB #imm so we fake it with ADC. */ 845 846 | SBB '#' EXPR ',' REG 847 { id24 (2, 0x70, 0x20); F ($5, 20, 4); NBIMM ($3, 12); } 848 849 /* ---------------------------------------------------------------------- */ 850 851 | MOVCO REG ',' '[' REG ']' 852 { rx_check_v2 (); B3 (0xfd, 0x27, 0x00); F ($5, 16, 4); F ($2, 20, 4); } 853 854 /* ---------------------------------------------------------------------- */ 855 856 | MOVLI '[' REG ']' ',' REG 857 { rx_check_v2 (); B3 (0xfd, 0x2f, 0x00); F ($3, 16, 4); F ($6, 20, 4); } 858 859 /* ---------------------------------------------------------------------- */ 860 861 | EMACA REG ',' REG ',' ACC 862 { rx_check_v2 (); id24 (2, 0x07, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 863 | EMSBA REG ',' REG ',' ACC 864 { rx_check_v2 (); id24 (2, 0x47, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 865 | EMULA REG ',' REG ',' ACC 866 { rx_check_v2 (); id24 (2, 0x03, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 867 | MACLH REG ',' REG ',' ACC 868 { rx_check_v2 (); id24 (2, 0x06, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 869 | MSBHI REG ',' REG ',' ACC 870 { rx_check_v2 (); id24 (2, 0x44, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 871 | MSBLH REG ',' REG ',' ACC 872 { rx_check_v2 (); id24 (2, 0x46, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 873 | MSBLO REG ',' REG ',' ACC 874 { rx_check_v2 (); id24 (2, 0x45, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 875 | MULLH REG ',' REG ',' ACC 876 { rx_check_v2 (); id24 (2, 0x02, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 877 | MVFACGU { sub_op = 3; } mvfa_op 878 | MVTACGU REG ',' ACC 879 { rx_check_v2 (); id24 (2, 0x17, 0x30); F ($4, 16, 1); F ($2, 20, 4); } 880 | RACL '#' EXPR ',' ACC 881 { rx_check_v2 (); id24 (2, 0x19, 0x00); F ($5, 16, 1); 882 if (rx_uintop ($3, 4) && $3.X_add_number == 1) 883 ; 884 else if (rx_uintop ($3, 4) && $3.X_add_number == 2) 885 F (1, 19, 1); 886 else 887 as_bad (_("RACL expects #1 or #2"));} 888 | RDACL '#' EXPR ',' ACC 889 { rx_check_v2 (); id24 (2, 0x19, 0x40); F ($5, 16, 1); 890 if (rx_uintop ($3, 4) && $3.X_add_number == 1) 891 ; 892 else if (rx_uintop ($3, 4) && $3.X_add_number == 2) 893 F (1, 19, 1); 894 else 895 as_bad (_("RDACL expects #1 or #2"));} 896 | RDACW '#' EXPR ',' ACC 897 { rx_check_v2 (); id24 (2, 0x18, 0x40); F ($5, 16, 1); 898 if (rx_uintop ($3, 4) && $3.X_add_number == 1) 899 ; 900 else if (rx_uintop ($3, 4) && $3.X_add_number == 2) 901 F (1, 19, 1); 902 else 903 as_bad (_("RDACW expects #1 or #2"));} 904 905 /* ---------------------------------------------------------------------- */ 906 907 ; 908 909 /* ====================================================================== */ 910 911 op_subadd 912 : REG ',' REG 913 { B2 (0x43 + (sub_op<<2), 0); F ($1, 8, 4); F ($3, 12, 4); } 914 | disp '[' REG ']' DOT_UB ',' REG 915 { B2 (0x40 + (sub_op<<2), 0); F ($3, 8, 4); F ($7, 12, 4); DSP ($1, 6, BSIZE); } 916 | disp '[' REG ']' memex ',' REG 917 { B3 (MEMEX, sub_op<<2, 0); F ($5, 8, 2); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, sizemap[$5]); } 918 | REG ',' REG ',' REG 919 { id24 (4, sub_op<<4, 0), F ($5, 12, 4), F ($1, 16, 4), F ($3, 20, 4); } 920 ; 921 922 /* sbb, neg, adc, abs, max, min, div, divu, tst, not, xor, stz, stnz, emul, emulu */ 923 924 op_dp20_rm_l 925 : REG ',' REG 926 { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); } 927 | disp '[' REG ']' opt_l ',' REG 928 { B4 (MEMEX, 0xa0, 0x00 + sub_op, 0x00); 929 F ($3, 24, 4); F ($7, 28, 4); DSP ($1, 14, LSIZE); } 930 ; 931 932 /* neg, adc, abs, max, min, div, divu, tst, not, xor, stz, stnz, emul, emulu */ 933 934 op_dp20_rm 935 : REG ',' REG 936 { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); } 937 | disp '[' REG ']' DOT_UB ',' REG 938 { id24 (1, 0x00 + (sub_op<<2), 0x00); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, BSIZE); } 939 | disp '[' REG ']' memex ',' REG 940 { B4 (MEMEX, 0x20 + ($5 << 6), 0x00 + sub_op, 0x00); 941 F ($3, 24, 4); F ($7, 28, 4); DSP ($1, 14, sizemap[$5]); } 942 ; 943 944 op_dp20_i 945 : '#' EXPR ',' REG 946 { id24 (2, 0x70, sub_op<<4); F ($4, 20, 4); IMM ($2, 12); } 947 ; 948 949 op_dp20_rim 950 : op_dp20_rm 951 | op_dp20_i 952 ; 953 954 op_dp20_rim_l 955 : op_dp20_rm_l 956 | op_dp20_i 957 ; 958 959 op_dp20_rr 960 : REG ',' REG 961 { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); } 962 | REG 963 { B2 (0x7e, sub_op2 << 4); F ($1, 12, 4); } 964 ; 965 966 op_dp20_r 967 : REG ',' REG 968 { id24 (1, 0x4b + (sub_op2<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); } 969 ; 970 971 op_dp20_ri 972 : { rx_check_v2 (); } 973 op_dp20_r 974 | op_dp20_i 975 ; 976 977 /* xchg, utof, itof, emul, emulu */ 978 op_xchg 979 : REG ',' REG 980 { id24 (1, 0x03 + (sub_op<<2), 0); F ($1, 16, 4); F ($3, 20, 4); } 981 | disp '[' REG ']' DOT_UB ',' REG 982 { id24 (1, 0x00 + (sub_op<<2), 0); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, BSIZE); } 983 | disp '[' REG ']' memex ',' REG 984 { B4 (MEMEX, 0x20, 0x00 + sub_op, 0); F ($5, 8, 2); F ($3, 24, 4); F ($7, 28, 4); 985 DSP ($1, 14, sizemap[$5]); } 986 ; 987 988 /* 000:SHLR, 001:SHAR, 010:SHLL, 011:-, 100:ROTR, 101:REVW, 110:ROTL, 111:REVL */ 989 op_shift_rot 990 : REG ',' REG 991 { id24 (2, 0x60 + sub_op, 0); F ($1, 16, 4); F ($3, 20, 4); } 992 ; 993 op_shift 994 : '#' EXPR ',' REG 995 { B2 (0x68 + (sub_op<<1), 0); FE ($2, 7, 5); F ($4, 12, 4); } 996 | '#' EXPR ',' REG ',' REG 997 { id24 (2, 0x80 + (sub_op << 5), 0); FE ($2, 11, 5); F ($4, 16, 4); F ($6, 20, 4); } 998 | op_shift_rot 999 ; 1000 1001 float3_op 1002 : '#' EXPR ',' REG 1003 { rx_check_float_support (); id24 (2, 0x72, sub_op << 4); F ($4, 20, 4); O4 ($2); } 1004 | REG ',' REG 1005 { rx_check_float_support (); id24 (1, 0x83 + (sub_op << 2), 0); F ($1, 16, 4); F ($3, 20, 4); } 1006 | disp '[' REG ']' opt_l ',' REG 1007 { rx_check_float_support (); id24 (1, 0x80 + (sub_op << 2), 0); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, LSIZE); } 1008 | REG ',' REG ',' REG 1009 { rx_check_v2 (); id24 (4, 0x80 + (sub_op << 4), 0 ); F ($1, 16, 4); F ($3, 20, 4); F ($5, 12, 4); } 1010 ; 1011 1012 float2_op 1013 : { rx_check_float_support (); } 1014 '#' EXPR ',' REG 1015 { id24 (2, 0x72, sub_op << 4); F ($5, 20, 4); O4 ($3); } 1016 | float2_op_ni 1017 ; 1018 1019 float2_op_ni 1020 : { rx_check_float_support (); } 1021 REG ',' REG 1022 { id24 (1, 0x83 + (sub_op << 2), 0); F ($2, 16, 4); F ($4, 20, 4); } 1023 | { rx_check_float_support (); } 1024 disp '[' REG ']' opt_l ',' REG 1025 { id24 (1, 0x80 + (sub_op << 2), 0); F ($4, 16, 4); F ($8, 20, 4); DSP ($2, 14, LSIZE); } 1026 ; 1027 1028 mvfa_op 1029 : { rx_check_v2 (); } 1030 '#' EXPR ',' ACC ',' REG 1031 { id24 (2, 0x1e, sub_op << 4); F ($7, 20, 4); F ($5, 16, 1); 1032 if (rx_uintop ($3, 4)) 1033 { 1034 switch (exp_val ($3)) 1035 { 1036 case 0: 1037 F (1, 15, 1); 1038 break; 1039 case 1: 1040 F (1, 15, 1); 1041 F (1, 17, 1); 1042 break; 1043 case 2: 1044 break; 1045 default: 1046 as_bad (_("IMM expects #0 to #2"));} 1047 } else 1048 as_bad (_("IMM expects #0 to #2"));} 1049 ; 1050 1051 /* ====================================================================== */ 1052 1053 disp : { $$ = zero_expr (); } 1054 | EXPR { $$ = $1; } 1055 ; 1056 1057 flag : { need_flag = 1; } FLAG { need_flag = 0; $$ = $2; } 1058 ; 1059 1060 /* DOT_UB is not listed here, it's handled with a separate pattern. */ 1061 /* Use sizemap[$n] to get LSIZE etc. */ 1062 memex : DOT_B { $$ = 0; } 1063 | DOT_W { $$ = 1; } 1064 | { $$ = 2; } 1065 | DOT_L { $$ = 2; } 1066 | DOT_UW { $$ = 3; } 1067 ; 1068 1069 bwl : { $$ = LSIZE; } 1070 | DOT_B { $$ = BSIZE; } 1071 | DOT_W { $$ = WSIZE; } 1072 | DOT_L { $$ = LSIZE; } 1073 ; 1074 1075 bw : { $$ = 1; } 1076 | DOT_B { $$ = 0; } 1077 | DOT_W { $$ = 1; } 1078 ; 1079 1080 opt_l : {} 1081 | DOT_L {} 1082 ; 1083 1084 opt_b : {} 1085 | DOT_B {} 1086 ; 1087 1088 %% 1089 /* ====================================================================== */ 1090 1091 static struct 1092 { 1093 const char * string; 1094 int token; 1095 int val; 1096 } 1097 token_table[] = 1098 { 1099 { "r0", REG, 0 }, 1100 { "r1", REG, 1 }, 1101 { "r2", REG, 2 }, 1102 { "r3", REG, 3 }, 1103 { "r4", REG, 4 }, 1104 { "r5", REG, 5 }, 1105 { "r6", REG, 6 }, 1106 { "r7", REG, 7 }, 1107 { "r8", REG, 8 }, 1108 { "r9", REG, 9 }, 1109 { "r10", REG, 10 }, 1110 { "r11", REG, 11 }, 1111 { "r12", REG, 12 }, 1112 { "r13", REG, 13 }, 1113 { "r14", REG, 14 }, 1114 { "r15", REG, 15 }, 1115 1116 { "psw", CREG, 0 }, 1117 { "pc", CREG, 1 }, 1118 { "usp", CREG, 2 }, 1119 { "fpsw", CREG, 3 }, 1120 /* reserved */ 1121 /* reserved */ 1122 /* reserved */ 1123 { "wr", CREG, 7 }, 1124 1125 { "bpsw", CREG, 8 }, 1126 { "bpc", CREG, 9 }, 1127 { "isp", CREG, 10 }, 1128 { "fintv", CREG, 11 }, 1129 { "intb", CREG, 12 }, 1130 { "extb", CREG, 13 }, 1131 1132 { "pbp", CREG, 16 }, 1133 { "pben", CREG, 17 }, 1134 1135 { "bbpsw", CREG, 24 }, 1136 { "bbpc", CREG, 25 }, 1137 1138 { ".s", DOT_S, 0 }, 1139 { ".b", DOT_B, 0 }, 1140 { ".w", DOT_W, 0 }, 1141 { ".l", DOT_L, 0 }, 1142 { ".a", DOT_A , 0}, 1143 { ".ub", DOT_UB, 0 }, 1144 { ".uw", DOT_UW , 0}, 1145 1146 { "c", FLAG, 0 }, 1147 { "z", FLAG, 1 }, 1148 { "s", FLAG, 2 }, 1149 { "o", FLAG, 3 }, 1150 { "i", FLAG, 8 }, 1151 { "u", FLAG, 9 }, 1152 1153 { "a0", ACC, 0 }, 1154 { "a1", ACC, 1 }, 1155 1156 #define OPC(x) { #x, x, IS_OPCODE } 1157 OPC(ABS), 1158 OPC(ADC), 1159 OPC(ADD), 1160 { "and", AND_, IS_OPCODE }, 1161 OPC(BCLR), 1162 OPC(BCND), 1163 OPC(BMCND), 1164 OPC(BNOT), 1165 OPC(BRA), 1166 OPC(BRK), 1167 OPC(BSET), 1168 OPC(BSR), 1169 OPC(BTST), 1170 OPC(CLRPSW), 1171 OPC(CMP), 1172 OPC(DBT), 1173 OPC(DIV), 1174 OPC(DIVU), 1175 OPC(EDIV), 1176 OPC(EDIVU), 1177 OPC(EMACA), 1178 OPC(EMSBA), 1179 OPC(EMUL), 1180 OPC(EMULA), 1181 OPC(EMULU), 1182 OPC(FADD), 1183 OPC(FCMP), 1184 OPC(FDIV), 1185 OPC(FMUL), 1186 OPC(FREIT), 1187 OPC(FSQRT), 1188 OPC(FTOU), 1189 OPC(FSUB), 1190 OPC(FTOI), 1191 OPC(INT), 1192 OPC(ITOF), 1193 OPC(JMP), 1194 OPC(JSR), 1195 OPC(MVFACGU), 1196 OPC(MVFACHI), 1197 OPC(MVFACMI), 1198 OPC(MVFACLO), 1199 OPC(MVFC), 1200 OPC(MVTACGU), 1201 OPC(MVTACHI), 1202 OPC(MVTACLO), 1203 OPC(MVTC), 1204 OPC(MVTIPL), 1205 OPC(MACHI), 1206 OPC(MACLO), 1207 OPC(MACLH), 1208 OPC(MAX), 1209 OPC(MIN), 1210 OPC(MOV), 1211 OPC(MOVCO), 1212 OPC(MOVLI), 1213 OPC(MOVU), 1214 OPC(MSBHI), 1215 OPC(MSBLH), 1216 OPC(MSBLO), 1217 OPC(MUL), 1218 OPC(MULHI), 1219 OPC(MULLH), 1220 OPC(MULLO), 1221 OPC(MULU), 1222 OPC(NEG), 1223 OPC(NOP), 1224 OPC(NOT), 1225 OPC(OR), 1226 OPC(POP), 1227 OPC(POPC), 1228 OPC(POPM), 1229 OPC(PUSH), 1230 OPC(PUSHA), 1231 OPC(PUSHC), 1232 OPC(PUSHM), 1233 OPC(RACL), 1234 OPC(RACW), 1235 OPC(RDACL), 1236 OPC(RDACW), 1237 OPC(REIT), 1238 OPC(REVL), 1239 OPC(REVW), 1240 OPC(RMPA), 1241 OPC(ROLC), 1242 OPC(RORC), 1243 OPC(ROTL), 1244 OPC(ROTR), 1245 OPC(ROUND), 1246 OPC(RTE), 1247 OPC(RTFI), 1248 OPC(RTS), 1249 OPC(RTSD), 1250 OPC(SAT), 1251 OPC(SATR), 1252 OPC(SBB), 1253 OPC(SCCND), 1254 OPC(SCMPU), 1255 OPC(SETPSW), 1256 OPC(SHAR), 1257 OPC(SHLL), 1258 OPC(SHLR), 1259 OPC(SMOVB), 1260 OPC(SMOVF), 1261 OPC(SMOVU), 1262 OPC(SSTR), 1263 OPC(STNZ), 1264 OPC(STOP), 1265 OPC(STZ), 1266 OPC(SUB), 1267 OPC(SUNTIL), 1268 OPC(SWHILE), 1269 OPC(TST), 1270 OPC(UTOF), 1271 OPC(WAIT), 1272 OPC(XCHG), 1273 OPC(XOR), 1274 }; 1275 1276 #define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0])) 1277 1278 static struct 1279 { 1280 const char * string; 1281 int token; 1282 } 1283 condition_opcode_table[] = 1284 { 1285 { "b", BCND }, 1286 { "bm", BMCND }, 1287 { "sc", SCCND }, 1288 }; 1289 1290 #define NUM_CONDITION_OPCODES (sizeof (condition_opcode_table) / sizeof (condition_opcode_table[0])) 1291 1292 static struct 1293 { 1294 const char * string; 1295 int val; 1296 } 1297 condition_table[] = 1298 { 1299 { "z", 0 }, 1300 { "eq", 0 }, 1301 { "geu", 2 }, 1302 { "c", 2 }, 1303 { "gtu", 4 }, 1304 { "pz", 6 }, 1305 { "ge", 8 }, 1306 { "gt", 10 }, 1307 { "o", 12}, 1308 /* always = 14 */ 1309 { "nz", 1 }, 1310 { "ne", 1 }, 1311 { "ltu", 3 }, 1312 { "nc", 3 }, 1313 { "leu", 5 }, 1314 { "n", 7 }, 1315 { "lt", 9 }, 1316 { "le", 11 }, 1317 { "no", 13 } 1318 /* never = 15 */ 1319 }; 1320 1321 #define NUM_CONDITIONS (sizeof (condition_table) / sizeof (condition_table[0])) 1322 1323 void 1324 rx_lex_init (char * beginning, char * ending) 1325 { 1326 rx_init_start = beginning; 1327 rx_lex_start = beginning; 1328 rx_lex_end = ending; 1329 rx_in_brackets = 0; 1330 rx_last_token = 0; 1331 1332 setbuf (stdout, 0); 1333 } 1334 1335 static int 1336 check_condition (const char * base) 1337 { 1338 char * cp; 1339 unsigned int i; 1340 1341 if ((unsigned) (rx_lex_end - rx_lex_start) < strlen (base) + 1) 1342 return 0; 1343 if (memcmp (rx_lex_start, base, strlen (base))) 1344 return 0; 1345 cp = rx_lex_start + strlen (base); 1346 for (i = 0; i < NUM_CONDITIONS; i ++) 1347 { 1348 if (strcasecmp (cp, condition_table[i].string) == 0) 1349 { 1350 rx_lval.regno = condition_table[i].val; 1351 return 1; 1352 } 1353 } 1354 return 0; 1355 } 1356 1357 static int 1358 rx_lex (void) 1359 { 1360 unsigned int ci; 1361 char * save_input_pointer; 1362 1363 while (ISSPACE (*rx_lex_start) 1364 && rx_lex_start != rx_lex_end) 1365 rx_lex_start ++; 1366 1367 rx_last_exp_start = rx_lex_start; 1368 1369 if (rx_lex_start == rx_lex_end) 1370 return 0; 1371 1372 if (ISALPHA (*rx_lex_start) 1373 || (rx_pid_register != -1 && memcmp (rx_lex_start, "%pidreg", 7) == 0) 1374 || (rx_gp_register != -1 && memcmp (rx_lex_start, "%gpreg", 6) == 0) 1375 || (*rx_lex_start == '.' && ISALPHA (rx_lex_start[1]))) 1376 { 1377 unsigned int i; 1378 char * e; 1379 char save; 1380 1381 for (e = rx_lex_start + 1; 1382 e < rx_lex_end && ISALNUM (*e); 1383 e ++) 1384 ; 1385 save = *e; 1386 *e = 0; 1387 1388 if (strcmp (rx_lex_start, "%pidreg") == 0) 1389 { 1390 { 1391 rx_lval.regno = rx_pid_register; 1392 *e = save; 1393 rx_lex_start = e; 1394 rx_last_token = REG; 1395 return REG; 1396 } 1397 } 1398 1399 if (strcmp (rx_lex_start, "%gpreg") == 0) 1400 { 1401 { 1402 rx_lval.regno = rx_gp_register; 1403 *e = save; 1404 rx_lex_start = e; 1405 rx_last_token = REG; 1406 return REG; 1407 } 1408 } 1409 1410 if (rx_last_token == 0) 1411 for (ci = 0; ci < NUM_CONDITION_OPCODES; ci ++) 1412 if (check_condition (condition_opcode_table[ci].string)) 1413 { 1414 *e = save; 1415 rx_lex_start = e; 1416 rx_last_token = condition_opcode_table[ci].token; 1417 return condition_opcode_table[ci].token; 1418 } 1419 1420 for (i = 0; i < NUM_TOKENS; i++) 1421 if (strcasecmp (rx_lex_start, token_table[i].string) == 0 1422 && !(token_table[i].val == IS_OPCODE && rx_last_token != 0) 1423 && !(token_table[i].token == FLAG && !need_flag)) 1424 { 1425 rx_lval.regno = token_table[i].val; 1426 *e = save; 1427 rx_lex_start = e; 1428 rx_last_token = token_table[i].token; 1429 return token_table[i].token; 1430 } 1431 *e = save; 1432 } 1433 1434 if (rx_last_token == 0) 1435 { 1436 rx_last_token = UNKNOWN_OPCODE; 1437 return UNKNOWN_OPCODE; 1438 } 1439 1440 if (rx_last_token == UNKNOWN_OPCODE) 1441 return 0; 1442 1443 if (*rx_lex_start == '[') 1444 rx_in_brackets = 1; 1445 if (*rx_lex_start == ']') 1446 rx_in_brackets = 0; 1447 1448 if (rx_in_brackets 1449 || rx_last_token == REG 1450 || strchr ("[],#", *rx_lex_start)) 1451 { 1452 rx_last_token = *rx_lex_start; 1453 return *rx_lex_start ++; 1454 } 1455 1456 save_input_pointer = input_line_pointer; 1457 input_line_pointer = rx_lex_start; 1458 rx_lval.exp.X_md = 0; 1459 expression (&rx_lval.exp); 1460 1461 /* We parse but ignore any :<size> modifier on expressions. */ 1462 if (*input_line_pointer == ':') 1463 { 1464 char *cp; 1465 1466 for (cp = input_line_pointer + 1; *cp && cp < rx_lex_end; cp++) 1467 if (!ISDIGIT (*cp)) 1468 break; 1469 if (cp > input_line_pointer+1) 1470 input_line_pointer = cp; 1471 } 1472 1473 rx_lex_start = input_line_pointer; 1474 input_line_pointer = save_input_pointer; 1475 rx_last_token = EXPR; 1476 return EXPR; 1477 } 1478 1479 int 1480 rx_error (const char * str) 1481 { 1482 int len; 1483 1484 len = rx_last_exp_start - rx_init_start; 1485 1486 as_bad ("%s", rx_init_start); 1487 as_bad ("%*s^ %s", len, "", str); 1488 return 0; 1489 } 1490 1491 static int 1492 rx_intop (expressionS exp, int nbits, int opbits) 1493 { 1494 long v; 1495 long mask, msb; 1496 1497 if (exp.X_op == O_big) 1498 { 1499 if (nbits == 32) 1500 return 1; 1501 if (exp.X_add_number == -1) 1502 return 0; 1503 } 1504 else if (exp.X_op != O_constant) 1505 return 0; 1506 v = exp.X_add_number; 1507 1508 msb = 1UL << (opbits - 1); 1509 mask = (1UL << opbits) - 1; 1510 1511 if ((v & msb) && ! (v & ~mask)) 1512 v -= 1UL << opbits; 1513 1514 switch (nbits) 1515 { 1516 case 4: 1517 return -0x8 <= v && v <= 0x7; 1518 case 5: 1519 return -0x10 <= v && v <= 0x17; 1520 case 8: 1521 return -0x80 <= v && v <= 0x7f; 1522 case 16: 1523 return -0x8000 <= v && v <= 0x7fff; 1524 case 24: 1525 return -0x800000 <= v && v <= 0x7fffff; 1526 case 32: 1527 return 1; 1528 default: 1529 printf ("rx_intop passed %d\n", nbits); 1530 abort (); 1531 } 1532 return 1; 1533 } 1534 1535 static int 1536 rx_uintop (expressionS exp, int nbits) 1537 { 1538 unsigned long v; 1539 1540 if (exp.X_op != O_constant) 1541 return 0; 1542 v = exp.X_add_number; 1543 1544 switch (nbits) 1545 { 1546 case 4: 1547 return v <= 0xf; 1548 case 8: 1549 return v <= 0xff; 1550 case 16: 1551 return v <= 0xffff; 1552 case 24: 1553 return v <= 0xffffff; 1554 default: 1555 printf ("rx_uintop passed %d\n", nbits); 1556 abort (); 1557 } 1558 return 1; 1559 } 1560 1561 static int 1562 rx_disp3op (expressionS exp) 1563 { 1564 unsigned long v; 1565 1566 if (exp.X_op != O_constant) 1567 return 0; 1568 v = exp.X_add_number; 1569 if (v < 3 || v > 10) 1570 return 0; 1571 return 1; 1572 } 1573 1574 static int 1575 rx_disp5op (expressionS * exp, int msize) 1576 { 1577 long v; 1578 1579 if (exp->X_op != O_constant) 1580 return 0; 1581 v = exp->X_add_number; 1582 1583 switch (msize) 1584 { 1585 case BSIZE: 1586 if (0 <= v && v <= 31) 1587 return 1; 1588 break; 1589 case WSIZE: 1590 if (v & 1) 1591 return 0; 1592 if (0 <= v && v <= 63) 1593 { 1594 exp->X_add_number >>= 1; 1595 return 1; 1596 } 1597 break; 1598 case LSIZE: 1599 if (v & 3) 1600 return 0; 1601 if (0 <= v && v <= 127) 1602 { 1603 exp->X_add_number >>= 2; 1604 return 1; 1605 } 1606 break; 1607 } 1608 return 0; 1609 } 1610 1611 /* Just like the above, but allows a zero displacement. */ 1612 1613 static int 1614 rx_disp5op0 (expressionS * exp, int msize) 1615 { 1616 if (exp->X_op != O_constant) 1617 return 0; 1618 if (exp->X_add_number == 0) 1619 return 1; 1620 return rx_disp5op (exp, msize); 1621 } 1622 1623 static int 1624 exp_val (expressionS exp) 1625 { 1626 if (exp.X_op != O_constant) 1627 { 1628 rx_error (_("constant expected")); 1629 return 0; 1630 } 1631 return exp.X_add_number; 1632 } 1633 1634 static expressionS 1635 zero_expr (void) 1636 { 1637 /* Static, so program load sets it to all zeros, which is what we want. */ 1638 static expressionS zero; 1639 zero.X_op = O_constant; 1640 return zero; 1641 } 1642 1643 static int 1644 immediate (expressionS exp, int type, int pos, int bits) 1645 { 1646 /* We will emit constants ourself here, so negate them. */ 1647 if (type == RXREL_NEGATIVE && exp.X_op == O_constant) 1648 exp.X_add_number = - exp.X_add_number; 1649 if (type == RXREL_NEGATIVE_BORROW) 1650 { 1651 if (exp.X_op == O_constant) 1652 exp.X_add_number = - exp.X_add_number - 1; 1653 else 1654 rx_error (_("sbb cannot use symbolic immediates")); 1655 } 1656 1657 if (rx_intop (exp, 8, bits)) 1658 { 1659 rx_op (exp, 1, type); 1660 return 1; 1661 } 1662 else if (rx_intop (exp, 16, bits)) 1663 { 1664 rx_op (exp, 2, type); 1665 return 2; 1666 } 1667 else if (rx_uintop (exp, 16) && bits == 16) 1668 { 1669 rx_op (exp, 2, type); 1670 return 2; 1671 } 1672 else if (rx_intop (exp, 24, bits)) 1673 { 1674 rx_op (exp, 3, type); 1675 return 3; 1676 } 1677 else if (rx_intop (exp, 32, bits)) 1678 { 1679 rx_op (exp, 4, type); 1680 return 0; 1681 } 1682 else if (type == RXREL_SIGNED) 1683 { 1684 /* This is a symbolic immediate, we will relax it later. */ 1685 rx_relax (RX_RELAX_IMM, pos); 1686 rx_op (exp, linkrelax ? 4 : 1, type); 1687 return 1; 1688 } 1689 else 1690 { 1691 /* Let the linker deal with it. */ 1692 rx_op (exp, 4, type); 1693 return 0; 1694 } 1695 } 1696 1697 static int 1698 displacement (expressionS exp, int msize) 1699 { 1700 int val; 1701 int vshift = 0; 1702 1703 if (exp.X_op == O_symbol 1704 && exp.X_md) 1705 { 1706 switch (exp.X_md) 1707 { 1708 case BFD_RELOC_GPREL16: 1709 switch (msize) 1710 { 1711 case BSIZE: 1712 exp.X_md = BFD_RELOC_RX_GPRELB; 1713 break; 1714 case WSIZE: 1715 exp.X_md = BFD_RELOC_RX_GPRELW; 1716 break; 1717 case LSIZE: 1718 exp.X_md = BFD_RELOC_RX_GPRELL; 1719 break; 1720 } 1721 O2 (exp); 1722 return 2; 1723 } 1724 } 1725 1726 if (exp.X_op == O_subtract) 1727 { 1728 exp.X_md = BFD_RELOC_RX_DIFF; 1729 O2 (exp); 1730 return 2; 1731 } 1732 1733 if (exp.X_op != O_constant) 1734 { 1735 rx_error (_("displacements must be constants")); 1736 return -1; 1737 } 1738 val = exp.X_add_number; 1739 1740 if (val == 0) 1741 return 0; 1742 1743 switch (msize) 1744 { 1745 case BSIZE: 1746 break; 1747 case WSIZE: 1748 if (val & 1) 1749 rx_error (_("word displacement not word-aligned")); 1750 vshift = 1; 1751 break; 1752 case LSIZE: 1753 if (val & 3) 1754 rx_error (_("long displacement not long-aligned")); 1755 vshift = 2; 1756 break; 1757 default: 1758 as_bad (_("displacement with unknown size (internal bug?)\n")); 1759 break; 1760 } 1761 1762 val >>= vshift; 1763 exp.X_add_number = val; 1764 1765 if (0 <= val && val <= 255 ) 1766 { 1767 O1 (exp); 1768 return 1; 1769 } 1770 1771 if (0 <= val && val <= 65535) 1772 { 1773 O2 (exp); 1774 return 2; 1775 } 1776 if (val < 0) 1777 rx_error (_("negative displacements not allowed")); 1778 else 1779 rx_error (_("displacement too large")); 1780 return -1; 1781 } 1782 1783 static void 1784 rtsd_immediate (expressionS exp) 1785 { 1786 int val; 1787 1788 if (exp.X_op != O_constant) 1789 { 1790 rx_error (_("rtsd size must be constant")); 1791 return; 1792 } 1793 val = exp.X_add_number; 1794 if (val & 3) 1795 rx_error (_("rtsd size must be multiple of 4")); 1796 1797 if (val < 0 || val > 1020) 1798 rx_error (_("rtsd size must be 0..1020")); 1799 1800 val >>= 2; 1801 exp.X_add_number = val; 1802 O1 (exp); 1803 } 1804 1805 static void 1806 rx_range (expressionS exp, int minv, int maxv) 1807 { 1808 int val; 1809 1810 if (exp.X_op != O_constant) 1811 return; 1812 1813 val = exp.X_add_number; 1814 if (val < minv || val > maxv) 1815 as_warn (_("Value %d out of range %d..%d"), val, minv, maxv); 1816 } 1817 1818 static void 1819 rx_check_float_support (void) 1820 { 1821 if (rx_cpu == RX100 || rx_cpu == RX200) 1822 rx_error (_("target CPU type does not support floating point instructions")); 1823 } 1824 1825 static void 1826 rx_check_v2 (void) 1827 { 1828 if (rx_cpu < RXV2) 1829 rx_error (_("target CPU type does not support v2 instructions")); 1830 } 1831