}
static int
-lex_opr (uint8_t *buffer, int *n_bytes, expressionS *exp)
+lex_opr (uint8_t *buffer, int *n_bytes, expressionS *exp,
+ bool immediate_ok)
{
char *ilp = input_line_pointer;
uint8_t *xb = buffer;
*xb = 0;
if (lex_imm_e4 (&imm))
{
+ if (!immediate_ok)
+ {
+ as_bad (_("An immediate value in a source operand is inappropriate"));
+ return 0;
+ }
if (imm > 0)
*xb = imm;
else
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (lex_opr (buffer, &n_bytes, &exp))
+ if (lex_opr (buffer, &n_bytes, &exp, false))
{
/* Large constant direct values are more efficiently encoded as ext24 mode.
Otherwise a decision has to be deferred to a relax. */
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, true))
goto fail;
int size = size_from_suffix (insn, 0);
uint8_t buffer1[4];
int n_bytes1;
expressionS exp1;
- if (!lex_opr (buffer1, &n_bytes1, &exp1))
+ if (!lex_opr (buffer1, &n_bytes1, &exp1, false))
goto fail;
if (!lex_match (','))
uint8_t buffer2[4];
int n_bytes2;
expressionS exp2;
- if (!lex_opr (buffer2, &n_bytes2, &exp2))
+ if (!lex_opr (buffer2, &n_bytes2, &exp2, false))
goto fail;
int size1 = size_from_suffix (insn, 0);
}
static int
-reg_opr (const struct instruction *insn, int allowed_regs)
+reg_opr (const struct instruction *insn, int allowed_regs,
+ bool immediate_ok)
{
char *ilp = input_line_pointer;
int reg;
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (lex_opr (buffer, &n_bytes, &exp))
+ if (lex_opr (buffer, &n_bytes, &exp, immediate_ok))
{
/* Large constant direct values are more efficiently encoded as ext24 mode.
Otherwise a decision has to be deferred to a relax. */
static int
-regdxy_opr (const struct instruction *insn)
+regdxy_opr_dest (const struct instruction *insn)
{
- return reg_opr (insn, REG_BIT_Dn | REG_BIT_XY);
+ return reg_opr (insn, REG_BIT_Dn | REG_BIT_XY, false);
}
+static int
+regdxy_opr_src (const struct instruction *insn)
+{
+ return reg_opr (insn, REG_BIT_Dn | REG_BIT_XY, true);
+}
+
+
static int
regd_opr (const struct instruction *insn)
{
- return reg_opr (insn, REG_BIT_Dn);
+ return reg_opr (insn, REG_BIT_Dn, true);
}
+/* OP0: S; OP1: destination OPR */
+static int
+regs_opr_dest (const struct instruction *insn)
+{
+ return reg_opr (insn, 0x1U << REG_S, false);
+}
+
+/* OP0: S; OP1: source OPR */
static int
-regs_opr (const struct instruction *insn)
+regs_opr_src (const struct instruction *insn)
{
- return reg_opr (insn, 0x1U << REG_S);
+ return reg_opr (insn, 0x1U << REG_S, true);
}
static int
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
int size = size_from_suffix (insn, 0);
uint8_t buffer1[4];
int n_bytes1;
expressionS exp1;
- if (!lex_opr (buffer1, &n_bytes1, &exp1))
+ if (!lex_opr (buffer1, &n_bytes1, &exp1, false))
goto fail;
uint8_t buffer2[4];
int n_bytes2;
expressionS exp2;
- if (!lex_opr (buffer2, &n_bytes2, &exp2))
+ if (!lex_opr (buffer2, &n_bytes2, &exp2, false))
goto fail;
char *f = s12z_new_insn (1 + n_bytes1 + n_bytes2);
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
return 0;
char *f = s12z_new_insn (1 + n_bytes);
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (lex_opr (buffer, &n_bytes, &exp))
+ if (lex_opr (buffer, &n_bytes, &exp, false))
{
char *f = s12z_new_insn (n_bytes + 2);
number_to_chars_bigendian (f++, insn->opc, 1);
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
gas_assert (n_bytes == 1);
uint8_t buffer[4];
int n_opr_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_opr_bytes, &exp))
+ if (!lex_opr (buffer, &n_opr_bytes, &exp, false))
goto fail;
if (!lex_match (','))
int n_opr_bytes1;
expressionS exp1;
- if (!lex_opr (buffer1, &n_opr_bytes1, &exp1))
+ if (!lex_opr (buffer1, &n_opr_bytes1, &exp1, false))
goto fail;
n_bytes += n_opr_bytes1;
{
immediate = true;
}
- else if (!lex_opr (buffer2, &n_opr_bytes2, &exp2))
+ else if (!lex_opr (buffer2, &n_opr_bytes2, &exp2, false))
goto fail;
uint8_t sb = 0x20;
int n_opr_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_opr_bytes, &exp))
+ if (!lex_opr (buffer, &n_opr_bytes, &exp, false))
goto fail;
if (!lex_match (','))
int n_opr_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_opr_bytes, &exp))
+ if (!lex_opr (buffer, &n_opr_bytes, &exp, false))
goto fail;
if (!lex_match (','))
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
if (!lex_match (','))
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
if (!lex_match (','))
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
if (!lex_match (','))
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
if (!lex_match (','))
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
if (!lex_match (','))
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
if (!lex_match (','))
uint8_t buffer[4];
int n_bytes;
expressionS exp;
- if (!lex_opr (buffer, &n_bytes, &exp))
+ if (!lex_opr (buffer, &n_bytes, &exp, false))
goto fail;
if (!lex_match (','))
{"tfr", 1, 0x9e, tfr, 0},
{"zex", 1, 0x9e, tfr, 0},
- {"ld", 1, 0xa0, regdxy_opr, 0xb0},
+ {"ld", 1, 0xa0, regdxy_opr_src, 0xb0},
{"jmp", 1, 0xaa, opr, 0xba},
{"jsr", 1, 0xab, opr, 0xbb},
{"exg", 1, 0xae, tfr, 0},
{"sex", 1, 0xae, tfr, 0},
- {"st", 1, 0xc0, regdxy_opr, 0xd0},
+ {"st", 1, 0xc0, regdxy_opr_dest, 0xd0},
{"andcc", 1, 0xce, imm8, 0},
{"orcc", 1, 0xde, imm8, 0},
{"btgl.l", 1, 0xee, bm_opr_reg, 0},
{"cmp", 1, 0xe0, regdxy_imm, 0},
- {"cmp", 1, 0xf0, regdxy_opr, 0},
+ {"cmp", 1, 0xf0, regdxy_opr_src, 0},
{"cmp", 1, 0xfc, regx_regy, 0},
{"sub", 1, 0xfd, regd6_regx_regy, 0},
/* Page 2 */
/* The -10 below is a kludge. The opcode is in fact 0x00 */
- {"ld", 2, -10, regs_opr, 0},
+ {"ld", 2, -10, regs_opr_src, 0},
/* The -9 below is a kludge. The opcode is in fact 0x01 */
- {"st", 2, -9, regs_opr, 0},
+ {"st", 2, -9, regs_opr_dest, 0},
/* The -8 below is a kludge. The opcode is in fact 0x02 */
- {"cmp", 2, -8, regs_opr, 0},
+ {"cmp", 2, -8, regs_opr_src, 0},
/* The -7 below is a kludge. The opcode is in fact 0x03 */
{"ld", 2, -7, regs_imm, 0},