From 8805103910cfd8201e621cb766f404c585f3e46e Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 11 Jan 2001 20:19:17 +0000 Subject: [PATCH] Fix gas 68HC12 indexed addressing code generation --- gas/ChangeLog | 10 +++++ gas/config/tc-m68hc11.c | 70 +++++++++++++++++++---------- gas/testsuite/ChangeLog | 5 +++ gas/testsuite/gas/m68hc11/opers12.d | 19 +++++--- gas/testsuite/gas/m68hc11/opers12.s | 45 +++++++++++++++---- 5 files changed, 112 insertions(+), 37 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index d9a5dd9116..96df47a8ea 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2001-01-11 Stephane Carrez + + * config/tc-m68hc11.c (md_estimate_size_before_relax): Fix + STATE_INDEXED_OFFSET when the symbol is undefined (16-bit offset). + (build_indexed_byte): Don't relax indexed byte, use 16-bit offset + and fix_new_exp() instead. + (md_convert_frag): For indexed post byte use the symbol value + rather than the displacement. + (md_relax_table): Fix indexed offset relax. + 2001-01-11 Stephane Carrez * config/tc-m68hc11.c (md_estimate_size_before_relax):Don't diff --git a/gas/config/tc-m68hc11.c b/gas/config/tc-m68hc11.c index 4bbaaac9c7..9dcaa14926 100644 --- a/gas/config/tc-m68hc11.c +++ b/gas/config/tc-m68hc11.c @@ -85,7 +85,7 @@ relax_typeS md_relax_table[] = /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */ {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)}, {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)}, - {0, 0, 1, 0}, + {0, 0, 2, 0}, {1, 1, 0, 0}, /* Relax for dbeq/ibeq/tbeq r,: @@ -1754,15 +1754,26 @@ build_indexed_byte (op, format, move_insn) return 3; } } - f = frag_more (1); - number_to_chars_bigendian (f, byte, 1); -#if 0 - fix_new_exp (frag_now, f - frag_now->fr_literal, 2, - &op->exp, false, BFD_RELOC_16); -#endif - frag_var (rs_machine_dependent, 2, 2, - ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF), - op->exp.X_add_symbol, val, f); + if (op->reg1 != REG_PC) + { + byte = (byte << 3) | 0xe2; + f = frag_more (1); + number_to_chars_bigendian (f, byte, 1); + + f = frag_more (2); + fix_new_exp (frag_now, f - frag_now->fr_literal, 2, + &op->exp, false, BFD_RELOC_16); + number_to_chars_bigendian (f, 0, 2); + } + else + { + f = frag_more (1); + number_to_chars_bigendian (f, byte, 1); + frag_var (rs_machine_dependent, 2, 2, + ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF), + op->exp.X_add_symbol, + op->exp.X_add_number, f); + } return 3; } @@ -2425,6 +2436,7 @@ md_convert_frag (abfd, sec, fragP) fragS *fragP; { fixS *fixp; + long value; long disp; char *buffer_address = fragP->fr_literal; @@ -2434,8 +2446,8 @@ md_convert_frag (abfd, sec, fragP) buffer_address += fragP->fr_fix; /* The displacement of the address, from current location. */ - disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0; - disp = (disp + fragP->fr_offset) - object_address; + value = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0; + disp = (value + fragP->fr_offset) - object_address; disp += symbol_get_frag (fragP->fr_symbol)->fr_address; switch (fragP->fr_subtype) @@ -2485,24 +2497,37 @@ md_convert_frag (abfd, sec, fragP) break; case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5): - fragP->fr_opcode[0] = fragP->fr_opcode[0] << 5; - fragP->fr_opcode[0] |= disp & 0x1f; + fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6; + if ((fragP->fr_opcode[0] & 0x0ff) == 0x0c0) + fragP->fr_opcode[0] |= disp & 0x1f; + else + fragP->fr_opcode[0] |= value & 0x1f; break; case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9): fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3); fragP->fr_opcode[0] |= 0xE0; - fix_new (fragP, fragP->fr_fix + 1, 1, + fix_new (fragP, fragP->fr_fix, 1, fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8); fragP->fr_fix += 1; break; case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16): fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3); - fragP->fr_opcode[0] |= 0xE2; - fix_new (fragP, fragP->fr_fix, 2, - fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16); - fragP->fr_fix += 1; + fragP->fr_opcode[0] |= 0xe2; + if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa) + { + fixp = fix_new (fragP, fragP->fr_fix, 2, + fragP->fr_symbol, fragP->fr_offset, + 1, BFD_RELOC_16_PCREL); + fixp->fx_pcrel_adjust = 2; + } + else + { + fix_new (fragP, fragP->fr_fix, 2, + fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16); + } + fragP->fr_fix += 2; break; case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE): @@ -2621,13 +2646,12 @@ md_estimate_size_before_relax (fragP, segment) else { /* Switch the indexed operation to 16-bit mode. */ - if ((fragP->fr_opcode[1] & 0x21) == 0x20) - fragP->fr_opcode[1] = (fragP->fr_opcode[1] >> 3) | 0xc0 | 0x02; - + fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3; + fragP->fr_opcode[0] |= 0xe2; fragP->fr_fix++; fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16); - fragP->fr_fix += 2; + fragP->fr_fix++; frag_wane (fragP); } break; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index ba4c11cefd..1c6cd51590 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2001-01-11 Stephane Carrez + + * gas/m68hc11/opers12.s: Add more tests for index post byte. + * gas/m68hc11/opers12.d: Likewise. + 2001-01-11 Stephane Carrez * gas/m68hc11/all.exp: Add new tests for dwarf2. diff --git a/gas/testsuite/gas/m68hc11/opers12.d b/gas/testsuite/gas/m68hc11/opers12.d index 2fbd3ddf07..e6cdce0297 100644 --- a/gas/testsuite/gas/m68hc11/opers12.d +++ b/gas/testsuite/gas/m68hc11/opers12.d @@ -25,7 +25,7 @@ Disassembly of section .text: 0+031 ldaa \[257,Y\] 0+035 ldab \[32767,SP\] 0+039 ldd \[32768,PC\] -0+03d ldd 0,PC +0+03d ldd 9,PC 0+040 std A,X 0+042 ldx B,X 0+044 stx D,Y @@ -68,9 +68,9 @@ Disassembly of section .text: 0+0b8 trap #128 0+0ba trap #255 0+0bc movw 1,X, 2,X -0+0c0 movw 0+0ffff , 0000ffff -0+0c6 movw 0+0ffff , 1,X -0+0cb movw #0+0ffff , 1,X +0+0c0 movw 0+0ffff , 0000ffff +0+0c6 movw 0+0ffff , 1,X +0+0cb movw #0+0ffff , 1,X 0+0d0 movw 0+03 , 0+08 0+0d6 movw #0+03 , 0+03 0+0dc movw #0+03 , 1,X @@ -78,4 +78,13 @@ Disassembly of section .text: 0+0e6 movw 0+03 , 2,X 0+0eb movw 0+04 , -2,X 0+0f0 rts - +0+0f1 leas 0,X +0+0f5 leax 4,Y +0+0f7 leax 100,X +0+0fb leas 110,SP +0+0ff leay 10,X +0+103 leas 10240,Y +0+107 leas 255,PC +0+10b leas 0,PC +0+10f leas 255,PC +0+113 leas 0,PC diff --git a/gas/testsuite/gas/m68hc11/opers12.s b/gas/testsuite/gas/m68hc11/opers12.s index b4a9c24282..94f8912211 100644 --- a/gas/testsuite/gas/m68hc11/opers12.s +++ b/gas/testsuite/gas/m68hc11/opers12.s @@ -6,11 +6,11 @@ globl start start: - anda [12,x] + anda [12,x] ; Indexed indirect ldaa #10 ldx L1 L1: ldy ,x - addd 1,y + addd 1,y ; Offset from register subd -1,y eora 15,y eora -16,y @@ -22,33 +22,36 @@ L1: ldy ,x orab -256,x anda 256,x andb -257,x - anda [12,x] + anda [12,x] ; Indexed indirect (16-bit offset) ldaa [257,y] ldab [32767,sp] ldd [32768,pc] ldd L1,pc - std a,x + std a,x ; Two-reg index ldx b,x stx d,y - addd 1,+x + addd 1,+x ; Pre-Auto inc addd 2,+x addd 8,+x - addd 1,sp+ + addd 1,sp+ ; Post-Auto inc addd 2,sp+ addd 8,sp+ - subd 1,-y + subd 1,-y ; Pre-Auto dec subd 2,-y subd 8,-y - addd 1,y- + addd 1,y- ; Post-Auto dec addd 2,y- addd 8,y- - std [d,x] + std [d,x] ; Indexed indirect with two reg index std [d,y] std [d,sp] std [d,pc] beq L1 lbeq start lbcc L2 +;; +;; Move insn with various operands +;; movb start, 1,x movw 1,x, start movb start, 1,+x @@ -80,3 +83,27 @@ L2: movw 3,+2,x movw 4,-2,x rts +;; +;; Post-index byte with relocation +;; +post_indexed_pb: +t1: + leas abort,x +t2: + leax t2-t1,y + leax toto,x + leas toto+titi,sp + leay titi,x + leas bb,y + leas min5b,pc + leas max5b,pc + leas min9b,pc + leas max9b,pc + +titi = 10 +toto = 100 +min5b= -15 +max5b= 15 +min9b= -255 +max9b= 255 +bb = 10240