From 8d8ad4eb57db5b28298a025d5d35bd2e10c297fd Mon Sep 17 00:00:00 2001 From: Sean Keys Date: Fri, 27 Jul 2012 22:33:22 +0000 Subject: [PATCH] 2012-07-27 Sean Keys gas/config/ * tc-xgate.c: Consolidated inc/dec/hi/low modifieres into one function. (xgate_parse_operand): Added %hi and %lo handling. gas/testsuite/gas/xgate * xgate.exp: Added hi/lo test. * hilo.d: New test file * hilo.s: Net test source file. --- gas/config/tc-xgate.c | 102 ++++++++++++++++++-------------------- gas/testsuite/gas/xgate/hilo.d | 26 ++++++++++ gas/testsuite/gas/xgate/hilo.s | 33 ++++++++++++ gas/testsuite/gas/xgate/xgate.exp | 1 + 4 files changed, 109 insertions(+), 53 deletions(-) create mode 100644 gas/testsuite/gas/xgate/hilo.d create mode 100644 gas/testsuite/gas/xgate/hilo.s diff --git a/gas/config/tc-xgate.c b/gas/config/tc-xgate.c index 7db84ea..19983e1 100644 --- a/gas/config/tc-xgate.c +++ b/gas/config/tc-xgate.c @@ -122,9 +122,7 @@ xgate_get_operands (char *, s_operand []); static register_id reg_name_search (char *); op_modifiers -xgate_determine_hi_low(char **); -op_modifiers -xgate_determine_increment(char **); +xgate_determine_modifiers(char **); void xgate_scan_operands (struct xgate_opcode *opcode, s_operand []); @@ -142,7 +140,7 @@ static unsigned int prev = 0; static unsigned char fixup_required = 0; /* Used to enable clipping of 16 bit operands into 8 bit constraints. */ -static unsigned char macroClipping = 0; +static unsigned char autoHiLo = 0; static char oper_check; static char flag_print_insn_syntax = 0; @@ -540,7 +538,7 @@ md_assemble (char *input_line) else { /* Insn is a simplified instruction - expand it out. */ - macroClipping = 1; + autoHiLo = 1; unsigned int i; /* skip past our ';' separator. */ @@ -581,7 +579,7 @@ md_assemble (char *input_line) } } } - macroClipping = 0; + autoHiLo = 0; input_line = saved_input_line; } @@ -971,8 +969,7 @@ xgate_get_operands (char *line, s_operand oprs[]) if (*line == '#') line++; - oprs[num_operands].mod = xgate_determine_hi_low (&line); - oprs[num_operands].mod = xgate_determine_increment (&line); + oprs[num_operands].mod = xgate_determine_modifiers (&line); if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE) line = xgate_parse_exp (line, &oprs[num_operands].exp); @@ -1063,8 +1060,10 @@ reg_name_search (char *name) return REG_NONE; } +/* Parse operand modifiers such as inc/dec/hi/low. */ + op_modifiers -xgate_determine_hi_low(char **line) +xgate_determine_modifiers(char **line) { char *local_line = line[0]; @@ -1078,21 +1077,13 @@ xgate_determine_hi_low(char **line) *line += 3; return MOD_LOAD_LOW; } - return MOD_NONE; -} - -op_modifiers -xgate_determine_increment(char **line) -{ - char *local_line = line[0]; - if (*(local_line + 2) == '+') - return MOD_POSTINC; + return MOD_POSTINC; if (strncasecmp (local_line, "-r", 2) == 0) { *line += 1; return MOD_PREDEC; - } + } return MOD_NONE; } @@ -1197,7 +1188,7 @@ xgate_parse_operand (struct xgate_opcode *opcode, int *bit_width, int where, char **op_con, - s_operand operand_two) + s_operand operand) { fixS *fixp = 0; char *op_constraint = *op_con; @@ -1216,24 +1207,24 @@ xgate_parse_operand (struct xgate_opcode *opcode, pp_fix = 0; *bit_width = 5; - if (operand_two.reg == REG_NONE) + if (operand.reg == REG_NONE) as_bad (_(": expected register name r0-r7 ") ); - op_mask = operand_two.reg; - if(operand_two.mod == MOD_POSTINC) + op_mask = operand.reg; + if(operand.mod == MOD_POSTINC) pp_fix = INCREMENT; - if(operand_two.mod == MOD_PREDEC) + if(operand.mod == MOD_PREDEC) pp_fix = DECREMENT; op_mask <<= 2; op_mask |= pp_fix; break; case 'r': /* Register operand. */ - if (operand_two.reg == REG_NONE) + if (operand.reg == REG_NONE) as_bad (_(": expected register name r0-r7 ")); *bit_width = 3; - op_mask = operand_two.reg; + op_mask = operand.reg; break; case 'i': /* Immediate value or expression expected. */ @@ -1253,15 +1244,16 @@ xgate_parse_operand (struct xgate_opcode *opcode, *bit_width = 0x0F; } /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */ - if (operand_two.exp.X_op == O_constant) + if (operand.exp.X_op == O_constant) { - op_mask = operand_two.exp.X_add_number; - if ((opcode->name[strlen (opcode->name) - 1] == 'l') && macroClipping) + op_mask = operand.exp.X_add_number; + if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo) + || operand.mod == MOD_LOAD_LOW) { op_mask &= 0x00FF; } - else if ((opcode->name[strlen (opcode->name) - 1]) == 'h' - && macroClipping) + else if (((opcode->name[strlen (opcode->name) - 1]) == 'h' + && autoHiLo) || operand.mod == MOD_LOAD_HIGH) { op_mask >>= 8; } @@ -1277,42 +1269,46 @@ xgate_parse_operand (struct xgate_opcode *opcode, } else { + /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24 + TODO fix. */ fixup_required = 1; if (*op_constraint == '8') { - if ((opcode->name[strlen (opcode->name) - 1] == 'l') - && macroClipping) + if (((opcode->name[strlen (opcode->name) - 1] == 'l') + && autoHiLo) || operand.mod == MOD_LOAD_LOW) { - fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE, + fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, BFD_RELOC_XGATE_24); - /* Should be BFD_RELOC_XGATE_IMM8_LO TODO fix. */ - fixp->fx_pcrel_adjust = 0; } - if ((opcode->name[strlen (opcode->name) - 1]) == 'h' - && macroClipping) + else if (((opcode->name[strlen (opcode->name) - 1]) == 'h' + && autoHiLo) || operand.mod == MOD_LOAD_HIGH ) { - fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE, + fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, BFD_RELOC_XGATE_IMM8_HI); - fixp->fx_pcrel_adjust = 0; } - if (!fixp) - as_bad (_(":unknown relocation")); + else + { + as_bad (_("you must use a hi/lo directive or 16-bit macro " + "to load a 16-bit value.")); + break; + } + fixp->fx_pcrel_adjust = 0; } else if (*op_constraint == '5') { - fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE, + fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, BFD_RELOC_XGATE_IMM5); fixp->fx_pcrel_adjust = 0; } else if (*op_constraint == '4') { - fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE, + fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, BFD_RELOC_XGATE_IMM4); fixp->fx_pcrel_adjust = 0; } else if (*op_constraint == '3') { - fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE, + fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, BFD_RELOC_XGATE_IMM3); fixp->fx_pcrel_adjust = 0; } @@ -1321,17 +1317,17 @@ xgate_parse_operand (struct xgate_opcode *opcode, as_bad (_(":unknown relocation constraint size")); } } - break; + break; case 'c': /* CCR register expected. */ *bit_width = 0; - if (operand_two.reg != REG_CCR) + if (operand.reg != REG_CCR) as_bad (_(": expected register name ccr ")); - break; + break; case 'p': /* PC register expected. */ *bit_width = 0; - if (operand_two.reg != REG_PC) + if (operand.reg != REG_PC) as_bad (_(": expected register name pc ")); break; @@ -1339,24 +1335,24 @@ xgate_parse_operand (struct xgate_opcode *opcode, (*op_con)++; op_constraint++; - if (operand_two.exp.X_op != O_register) + if (operand.exp.X_op != O_register) { if (*op_constraint == '9') { - fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, TRUE, + fixp = fix_new_exp (frag_now, where, 2, &operand.exp, TRUE, R_XGATE_PCREL_9); fixp->fx_pcrel_adjust = 1; } else if (*op_constraint == 'a') { - fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, TRUE, + fixp = fix_new_exp (frag_now, where, 2, &operand.exp, TRUE, R_XGATE_PCREL_10); fixp->fx_pcrel_adjust = 1; } } else { - as_fatal (_("Operand `%x' not recognized in fixup8."), operand_two.exp.X_op); + as_fatal (_("Operand `%x' not recognized in fixup8."), operand.exp.X_op); } break; case '?': diff --git a/gas/testsuite/gas/xgate/hilo.d b/gas/testsuite/gas/xgate/hilo.d new file mode 100644 index 0000000..32c0a68 --- /dev/null +++ b/gas/testsuite/gas/xgate/hilo.d @@ -0,0 +1,26 @@ +#objdump: -d --prefix-addresses --reloc +#as: +#name: hilo + +# Test for correct generation of XGATE insns when using the %hi and %lo modifiers. + +.*: +file format elf32\-xgate + +Disassembly of section .text: +0+0000 ldl R2, #0x88 +0+0002 ldh R2, #0x88 Abs\* 0x00008888 +0+0004 ldl R3, #0x44 +0+0006 ldh R3, #0x44 Abs\* 0x00004444 +0+0008 ldl R2, #0xff +0+000a ldh R2, #0xff Abs\* 0x0000ffff +0+000c ldl R3, #0x88 +0+000e ldh R3, #0x88 Abs\* 0x00008888 +0+0010 ldl R2, #0x00 + 10: R_XGATE_IMM8_HI .text +0+0012 ldh R2, #0x00 Abs\* 0x00000000 + 12: R_XGATE_IMM8_HI .text +0+0014 ldl R3, #0x18 + 14: R_XGATE_IMM8_LO .text +0+0016 ldh R3, #0x18 Abs\* 0x00001818 + 16: R_XGATE_IMM8_LO .text + diff --git a/gas/testsuite/gas/xgate/hilo.s b/gas/testsuite/gas/xgate/hilo.s new file mode 100644 index 0000000..c157a6a --- /dev/null +++ b/gas/testsuite/gas/xgate/hilo.s @@ -0,0 +1,33 @@ +# Test for correct generation of XGATE insns when using the %hi and %lo modifiers. + + .sect .text +;Test Constants +hiTestLo: + ldl R2, %hi(0x8844) +hiTestHi: + ldh R2, %hi(0x8844) +loTestLo: + ldl R3, %lo(0x8844) +loTestHi: + ldh R3, %lo(0x8844) +;Test Fixups +hiTestLoF: + ldl R2, %hi(test) +hiTestHiF: + ldh R2, %hi(test) +loTestLoF: + ldl R3, %lo(test) +loTestHiF: + ldh R3, %lo(test) +;Test Relocs +hiTestLoR: + ldl R2, %hi(symValue) +hiTestHiR: + ldh R2, %hi(symValue) +loTestLoR: + ldl R3, %lo(symValue) +loTestHiR: + ldh R3, %lo(symValue) + +symValue: +test = 0xff88 diff --git a/gas/testsuite/gas/xgate/xgate.exp b/gas/testsuite/gas/xgate/xgate.exp index 1af5e76..eb5296a 100644 --- a/gas/testsuite/gas/xgate/xgate.exp +++ b/gas/testsuite/gas/xgate/xgate.exp @@ -16,4 +16,5 @@ run_dump_test abi-xgate-32-32 run_dump_test insns-dwarf2 run_dump_test all_insns run_dump_test insns +run_dump_test hilo -- 2.7.4