diff options
author | Frank Ch. Eigler <fche@redhat.com> | 1998-07-30 19:41:18 +0000 |
---|---|---|
committer | Frank Ch. Eigler <fche@redhat.com> | 1998-07-30 19:41:18 +0000 |
commit | e21cafde4ee9e7380a4992242701677f64658b97 (patch) | |
tree | daa968fbae95d9750afd4099fa813e3020643e6d | |
parent | 2c5d6bf41b2deb70b736201b096df251b4ad64d5 (diff) | |
download | gdb-e21cafde4ee9e7380a4992242701677f64658b97.zip gdb-e21cafde4ee9e7380a4992242701677f64658b97.tar.gz gdb-e21cafde4ee9e7380a4992242701677f64658b97.tar.bz2 |
* Fix for PR 16389, brought over from d30v branch.
Thu Jul 30 21:38:43 1998 Frank Ch. Eigler <fche@cygnus.com>
* config/tc-d30v.c ({cur,prev}_left_kills_right_p): New variables.
(write_2_short): Emit warning if new flag is set.
(do_assemble): Set flags if left instruction is one of special
"right-instruction-killer" type.
-rw-r--r-- | gas/ChangeLog | 14 | ||||
-rw-r--r-- | gas/config/tc-d30v.c | 65 |
2 files changed, 77 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index a54ab3a..f8b451d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +Thu Jul 30 21:38:43 1998 Frank Ch. Eigler <fche@cygnus.com> + + * config/tc-d30v.c ({cur,prev}_left_kills_right_p): New variables. + (write_2_short): Emit warning if new flag is set. + (do_assemble): Set flags if left instruction is one of special + "right-instruction-killer" type. + +Tue Jun 28 18:12:28 1998 Stan Cox <scox@cygnus.com> + + * config/tc-sparc.c (md_number_to_chars, cons_fix_new_sparc): + Always output words in debug_info section as big endian. + (sparc_target_format): Choose correct bfd target. + (md_apply_fix3): Rename BFD_RELOC_SPARC_32LE to BFD_RELOC_SPARC_REV32. + Tue Jul 28 11:01:21 1998 Jeffrey A Law (law@cygnus.com) * config/tc-mn10300.c (md_assemble): Fix "errmsg" initialization diff --git a/gas/config/tc-d30v.c b/gas/config/tc-d30v.c index 46e5eb9..e0b5959 100644 --- a/gas/config/tc-d30v.c +++ b/gas/config/tc-d30v.c @@ -83,6 +83,11 @@ static int prev_mul32_p = 0; static int flag_explicitly_parallel = 0; static int flag_xp_state = 0; +/* Whether current and previous left sub-instruction disables + execution of right sub-instruction. */ +static int cur_left_kills_right_p = 0; +static int prev_left_kills_right_p = 0; + /* The known current alignment of the current section. */ static int d30v_current_align; static segT d30v_current_align_seg; @@ -223,6 +228,16 @@ check_range (num, bits, flags) if (bits == 32) return 0; + if (flags & OPERAND_SHIFT) + { + /* We know that all shifts are right by three bits.... */ + + if (flags & OPERAND_SIGNED) + num = (unsigned long) (((/*signed*/ long) num) >> 3); + else + num >>= 3; + } + if (flags & OPERAND_SIGNED) { max = (1 << (bits - 1))-1; @@ -770,6 +785,10 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx) case EXEC_SEQ: /* sequential */ if (opcode1->op->unit == IU) as_fatal (_("IU instruction may not be in the left container")); + if (prev_left_kills_right_p) + as_warn (_("special left instruction `%s' kills instruction " + "`%s' in right container"), + opcode1->op->name, opcode2->op->name); insn = FM01 | (insn1 << 32) | insn2; fx = fx->next; break; @@ -1404,6 +1423,45 @@ do_assemble (str, opcode, shortp, is_parallel) } } + /* Propagate left_kills_right status */ + if (insn != -1) + { + prev_left_kills_right_p = cur_left_kills_right_p; + + if (opcode->op->flags_set & FLAG_LKR) + { + cur_left_kills_right_p = 1; + + if (strcmp (opcode->op->name, "mvtsys") == 0) + { + /* Left kills right for only mvtsys only for PSW/PSWH/PSWL/flags target. */ + if ((myops[0].X_op == O_register) && + ((myops[0].X_add_number == OPERAND_CONTROL) || /* psw */ + (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+2) || /* pswh */ + (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+1) || /* pswl */ + (myops[0].X_add_number == OPERAND_FLAG+0) || /* f0 */ + (myops[0].X_add_number == OPERAND_FLAG+1) || /* f1 */ + (myops[0].X_add_number == OPERAND_FLAG+2) || /* f2 */ + (myops[0].X_add_number == OPERAND_FLAG+3) || /* f3 */ + (myops[0].X_add_number == OPERAND_FLAG+4) || /* f4 */ + (myops[0].X_add_number == OPERAND_FLAG+5) || /* f5 */ + (myops[0].X_add_number == OPERAND_FLAG+6) || /* f6 */ + (myops[0].X_add_number == OPERAND_FLAG+7))) /* f7 */ + { + cur_left_kills_right_p = 1; + } + else + { + /* Other mvtsys target registers don't kill right instruction. */ + cur_left_kills_right_p = 0; + } + } /* mvtsys */ + } + else + cur_left_kills_right_p = 0; + } + + return (insn); } @@ -1859,8 +1917,11 @@ d30v_align (n, pfill, label) temporarily when -g is in effect. */ int switched_seg_p = (d30v_current_align_seg != now_seg); - if (d30v_current_align >= n && !switched_seg_p) - return; + /* Do not assume that if 'd30v_current_align >= n' and + '! switched_seg_p' that it is safe to avoid performing + this alignement request. The alignment of the current frag + can be changed under our feet, for example by a .ascii + directive in the source code. cf testsuite/gas/d30v/reloc.s */ d30v_cleanup (); |