diff options
author | Alan Modra <amodra@gmail.com> | 1999-07-16 11:09:15 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 1999-07-16 11:09:15 +0000 |
commit | b4cac588aeb44effa7d92cf612ee95455d0524a7 (patch) | |
tree | b10974beaa5608d9d4e2883744f9ff4b6c72a1f4 /gas/config/tc-i386.c | |
parent | 318da145ed406877df06bea26279e67a38f41a31 (diff) | |
download | gdb-b4cac588aeb44effa7d92cf612ee95455d0524a7.zip gdb-b4cac588aeb44effa7d92cf612ee95455d0524a7.tar.gz gdb-b4cac588aeb44effa7d92cf612ee95455d0524a7.tar.bz2 |
* gas/config/tc-i386.c: Fix for immediates and displacements in 16-bit
mode when no insn suffix present, eg. push $0x12345678. Fix some
compiler warnings. Disallow immediate jump absolute.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r-- | gas/config/tc-i386.c | 104 |
1 files changed, 56 insertions, 48 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 7070995..30c9abf 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -949,7 +949,10 @@ tc_i386_fix_adjustable(fixP) #define BFD_RELOC_386_GOTOFF 0 #endif -int +static int +intel_float_operand PARAMS ((char *mnemonic)); + +static int intel_float_operand (mnemonic) char *mnemonic; { @@ -1245,7 +1248,6 @@ md_assemble (line) { register unsigned int overlap0, overlap1; - expressionS *exp; unsigned int overlap2; unsigned int found_reverse_match; int suffix_check; @@ -1969,6 +1971,8 @@ md_assemble (line) { /* Fakes a zero displacement assuming that i.types[op] holds the correct displacement size. */ + expressionS *exp; + exp = &disp_expressions[i.disp_operands++]; i.disps[op] = exp; exp->X_op = O_constant; @@ -2359,30 +2363,28 @@ md_assemble (line) { if (i.disps[n]->X_op == O_constant) { - if (i.types[n] & Disp8) - { - insn_size += 1; - p = frag_more (1); - md_number_to_chars (p, - (valueT) i.disps[n]->X_add_number, - 1); - } - else if (i.types[n] & Disp16) + int size = 4; + long val = (long) i.disps[n]->X_add_number; + + if (i.types[n] & (Disp8 | Disp16)) { - insn_size += 2; - p = frag_more (2); - md_number_to_chars (p, - (valueT) i.disps[n]->X_add_number, - 2); - } - else - { /* Disp32 */ - insn_size += 4; - p = frag_more (4); - md_number_to_chars (p, - (valueT) i.disps[n]->X_add_number, - 4); + long mask; + + size = 2; + mask = ~ (long) 0xffff; + if (i.types[n] & Disp8) + { + size = 1; + mask = ~ (long) 0xff; + } + + if ((val & mask) != 0 && (val & mask) != mask) + as_warn (_("%ld shortened to %ld"), + val, val & ~mask); } + insn_size += size; + p = frag_more (size); + md_number_to_chars (p, (valueT) val, size); } else if (i.types[n] & Disp32) { @@ -2415,30 +2417,27 @@ md_assemble (line) { if (i.imms[n]->X_op == O_constant) { - if (i.types[n] & (Imm8 | Imm8S)) - { - insn_size += 1; - p = frag_more (1); - md_number_to_chars (p, - (valueT) i.imms[n]->X_add_number, - 1); - } - else if (i.types[n] & Imm16) - { - insn_size += 2; - p = frag_more (2); - md_number_to_chars (p, - (valueT) i.imms[n]->X_add_number, - 2); - } - else + int size = 4; + long val = (long) i.imms[n]->X_add_number; + + if (i.types[n] & (Imm8 | Imm8S | Imm16)) { - insn_size += 4; - p = frag_more (4); - md_number_to_chars (p, - (valueT) i.imms[n]->X_add_number, - 4); + long mask; + + size = 2; + mask = ~ (long) 0xffff; + if (i.types[n] & (Imm8 | Imm8S)) + { + size = 1; + mask = ~ (long) 0xff; + } + if ((val & mask) != 0 && (val & mask) != mask) + as_warn (_("%ld shortened to %ld"), + val, val & ~mask); } + insn_size += size; + p = frag_more (size); + md_number_to_chars (p, (valueT) val, size); } else { /* not absolute_section */ @@ -2613,9 +2612,13 @@ i386_immediate (imm_start) } else if (exp->X_op == O_constant) { + int bigimm = Imm32; + if (flag_16bit_code ^ (i.prefix[DATA_PREFIX] != 0)) + bigimm = Imm16; + i.types[this_operand] |= - smallest_imm_type ((long) exp->X_add_number); - + (bigimm | smallest_imm_type ((long) exp->X_add_number)); + /* If a suffix is given, this operand may be shortended. */ switch (i.suffix) { @@ -3450,6 +3453,11 @@ i386_operand (operand_string) else if (*op_string == IMMEDIATE_PREFIX) { /* ... or an immediate */ ++op_string; + if (i.types[this_operand] & JumpAbsolute) + { + as_bad (_("Immediate operand illegal with absolute jump")); + return 0; + } if (!i386_immediate (op_string)) return 0; } |