diff options
Diffstat (limited to 'gas/config/tc-score.c')
-rw-r--r-- | gas/config/tc-score.c | 114 |
1 files changed, 74 insertions, 40 deletions
diff --git a/gas/config/tc-score.c b/gas/config/tc-score.c index f9657ba68a..fe45b00bad 100644 --- a/gas/config/tc-score.c +++ b/gas/config/tc-score.c @@ -281,7 +281,6 @@ static void do_rdrsrs (char *); static void do_rdsi16 (char *); static void do_rdrssi14 (char *); static void do_sub_rdsi16 (char *); -static void do_sub_rdi16 (char *); static void do_sub_rdrssi14 (char *); static void do_rdrsi5 (char *); static void do_rdrsi14 (char *); @@ -365,8 +364,6 @@ static const struct asm_opcode score_insns[] = {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4, do16_rdi4}, {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16, do_sub_rdsi16}, {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16, do_sub_rdsi16}, - {"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16, do_sub_rdi16}, - {"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16, do_sub_rdi16}, {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14, do_sub_rdrssi14}, {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14, do_sub_rdrssi14}, {"and", 0x00000020, 0x3e0003ff, 0x8000, Rd_Rs_Rs, do_rdrsrs}, @@ -796,6 +793,7 @@ int next_literal_pool_place = 0; int lit_pool_num = 1; symbolS *current_poolP = NULL; + static int end_of_line (char *str) { @@ -1014,7 +1012,7 @@ my_get_expression (expressionS * ep, char **str) /* Check if an immediate is valid. If so, convert it to the right format. */ static int -validate_immediate (int val, unsigned int data_type) +validate_immediate (int val, unsigned int data_type, int hex_p) { switch (data_type) { @@ -1042,8 +1040,47 @@ validate_immediate (int val, unsigned int data_type) return val; break; + case _SIMM14: + if (hex_p == 1) + { + if (!(val >= -0x2000 && val <= 0x3fff)) + { + return (int) FAIL; + } + } + else + { + if (!(val >= -8192 && val <= 8191)) + { + return (int) FAIL; + } + } + + return val; + break; + + case _SIMM16_NEG: + if (hex_p == 1) + { + if (!(val >= -0x7fff && val <= 0xffff && val != 0x8000)) + { + return (int) FAIL; + } + } + else + { + if (!(val >= -32767 && val <= 32768)) + { + return (int) FAIL; + } + } + + val = -val; + return val; + break; + default: - if (data_type == _SIMM14_NEG || data_type == _SIMM16_NEG || data_type == _IMM16_NEG) + if (data_type == _SIMM14_NEG || data_type == _IMM16_NEG) val = -val; if (score_df_range[data_type].range[0] <= val @@ -1069,6 +1106,9 @@ data_op2 (char **str, int shift, enum score_data_type data_type) inst.error = NULL; dataptr = * str; + /* Set hex_p to zero. */ + int hex_p = 0; + while ((*dataptr != '\0') && (*dataptr != '|') && (cnt <= MAX_LITERAL_POOL_SIZE)) /* 0x7c = ='|' */ { data_exp[cnt] = *dataptr; @@ -1104,23 +1144,30 @@ data_op2 (char **str, int shift, enum score_data_type data_type) } dataptr = (char *)data_exp; - if ((*dataptr == '0') && (*(dataptr + 1) == 'x') - && (data_type != _SIMM16_LA) - && (data_type != _VALUE_HI16) - && (data_type != _VALUE_LO16) - && (data_type != _IMM16) - && (data_type != _IMM15) - && (data_type != _IMM14) - && (data_type != _IMM4) - && (data_type != _IMM5) - && (data_type != _IMM8) - && (data_type != _IMM5_RSHIFT_1) - && (data_type != _IMM5_RSHIFT_2) - && (data_type != _SIMM14_NEG) - && (data_type != _IMM10_RSHIFT_2) - && (data_type != _GP_IMM15)) + if ((dataptr != NULL) + && (((strstr (dataptr, "0x")) != NULL) + || ((strstr (dataptr, "0X")) != NULL))) { - data_type += 24; + hex_p = 1; + if ((data_type != _SIMM16_LA) + && (data_type != _VALUE_HI16) + && (data_type != _VALUE_LO16) + && (data_type != _IMM16) + && (data_type != _IMM15) + && (data_type != _IMM14) + && (data_type != _IMM4) + && (data_type != _IMM5) + && (data_type != _IMM8) + && (data_type != _IMM5_RSHIFT_1) + && (data_type != _IMM5_RSHIFT_2) + && (data_type != _SIMM14) + && (data_type != _SIMM14_NEG) + && (data_type != _SIMM16_NEG) + && (data_type != _IMM10_RSHIFT_2) + && (data_type != _GP_IMM15)) + { + data_type += 24; + } } if ((inst.reloc.exp.X_add_number == 0) @@ -1194,7 +1241,7 @@ data_op2 (char **str, int shift, enum score_data_type data_type) if (data_type == _SIMM16_LA && inst.reloc.exp.X_unsigned == 1) { - value = validate_immediate (inst.reloc.exp.X_add_number, _SIMM16_LA_POS); + value = validate_immediate (inst.reloc.exp.X_add_number, _SIMM16_LA_POS, hex_p); if (value == (int) FAIL) /* for advance to check if this is ldis */ if ((inst.reloc.exp.X_add_number & 0xffff) == 0) { @@ -1205,7 +1252,7 @@ data_op2 (char **str, int shift, enum score_data_type data_type) } else { - value = validate_immediate (inst.reloc.exp.X_add_number, data_type); + value = validate_immediate (inst.reloc.exp.X_add_number, data_type, hex_p); } if (value == (int) FAIL) @@ -1314,19 +1361,6 @@ do_sub_rdsi16 (char *str) end_of_line (str); } -/* Handle subis/subis.c. */ - -static void -do_sub_rdi16 (char *str) -{ - skip_whitespace (str); - - if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL - && skip_past_comma (&str) != (int) FAIL - && data_op2 (&str, 1, _IMM16_NEG) != (int) FAIL) - end_of_line (str); -} - /* Handle addri/addri.c. */ static void @@ -2603,7 +2637,7 @@ exp_ldst_offset (char **str, int shift, unsigned int data_type) if (value == (int) FAIL) return (int) FAIL; - value = validate_immediate (inst.reloc.exp.X_add_number, data_type); + value = validate_immediate (inst.reloc.exp.X_add_number, data_type, 0); if (value == (int) FAIL) { if (data_type < 30) @@ -2746,7 +2780,7 @@ do_ldst_insn (char *str) } pre_inc = 1; - value = validate_immediate (inst.reloc.exp.X_add_number, _SIMM12); + value = validate_immediate (inst.reloc.exp.X_add_number, _SIMM12, 0); value &= (1 << score_df_range[_SIMM12].bits) - 1; ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK; inst.instruction &= ~OPC_PSEUDOLDST_MASK; @@ -2886,7 +2920,7 @@ do_ldst_insn (char *str) data_type += 24; } - value = validate_immediate (inst.reloc.exp.X_add_number, data_type); + value = validate_immediate (inst.reloc.exp.X_add_number, data_type, 0); if (value == (int) FAIL) { if (data_type < 30) @@ -4250,7 +4284,7 @@ do_macro_ldst_label (char *str) absolute_value = backup_str; inst.type = Rd_rvalueRs_SI15; if ((my_get_expression (&inst.reloc.exp, &backup_str) == (int) FAIL) - || (validate_immediate (inst.reloc.exp.X_add_number, _VALUE) == (int) FAIL) + || (validate_immediate (inst.reloc.exp.X_add_number, _VALUE, 0) == (int) FAIL) || (end_of_line (backup_str) == (int) FAIL)) { return; |