From 1328dc9844bf1fc941f648d0df5b7c2b3b5fcaba Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sun, 14 Jan 2001 05:14:45 +0000 Subject: [PATCH] Adds assembly and dis-assembly support for the HPPA wide mode, 16 bit forms of ldi, ldo, ldw and stw instructions. --- gas/ChangeLog | 6 +++ gas/config/tc-hppa.c | 89 ++++++++++++++++++++++++++-------------- include/opcode/ChangeLog | 7 ++++ include/opcode/hppa.h | 49 ++++++++++++---------- opcodes/ChangeLog | 4 ++ opcodes/hppa-dis.c | 4 +- 6 files changed, 106 insertions(+), 53 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 6073008904..11bc523c66 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2001-01-14 Alan Modra + + * config/tc-hppa.c (pa_ip): Store `a' flag in bit zero of operand + and don't bother storing `m' for "ce" completer. Tidy handling of + 'J' and 'K' operands to suit. Handle '<' and '>' operands. + Sun Jan 14 00:36:42 MET 2001 Jan Hubicka * tc-i386.h (TARGET_MACH): New macro. diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 159aa67be0..69c1e044a2 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -1,5 +1,5 @@ /* tc-hppa.c -- Assemble for the PA - Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 99, 2000 + Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -1855,10 +1855,10 @@ pa_ip (str) } else if (*args == 'e') { - /* Gross! Hide these values in the immediate field - of the instruction, then pull them out later. */ - opcode |= m << 8; - opcode |= a << 9; + /* Stash the ma/mb flag temporarily in the + instruction. We will use (and remove it) + later when handling 'J', 'K', '<' & '>'. */ + opcode |= a; continue; } } @@ -2922,26 +2922,22 @@ pa_ip (str) s = expr_end; if (the_insn.exp.X_op == O_constant) { - int a, m; + int mb; - /* XXX the completer stored away tibits of information + /* XXX the completer stored away tidbits of information for us to extract. We need a cleaner way to do this. Now that we have lots of letters again, it would be good to rethink this. */ - m = (opcode & (1 << 8)) != 0; - a = (opcode & (1 << 9)) != 0; - opcode &= ~ (3 << 8); + mb = opcode & 1; + opcode -= mb; num = evaluate_absolute (&the_insn); - if ((a == 1 && num >= 0) || (a == 0 && num < 0)) + if (mb != (num < 0)) break; CHECK_FIELD (num, 8191, -8192, 0); num = low_sign_unext (num, 14); INSERT_FIELD_AND_CONTINUE (opcode, num, 0); } - else - { - break; - } + break; /* Handle a 14 bit immediate at 31. */ case 'K': @@ -2950,31 +2946,62 @@ pa_ip (str) s = expr_end; if (the_insn.exp.X_op == O_constant) { - int a, m; + int mb; - /* XXX the completer stored away tibits of information - for us to extract. We need a cleaner way to do this. - Now that we have lots of letters again, it would be - good to rethink this. */ - m = (opcode & (1 << 8)) != 0; - a = (opcode & (1 << 9)) != 0; - opcode &= ~ (3 << 8); + mb = opcode & 1; + opcode -= mb; num = evaluate_absolute (&the_insn); - if ((a == 1 && num < 0) || (a == 0 && num > 0)) + if (mb == (num < 0)) break; if (num % 4) break; CHECK_FIELD (num, 8191, -8192, 0); - if (num < 0) - opcode |= 1; - num &= 0x1fff; - num >>= 2; - INSERT_FIELD_AND_CONTINUE (opcode, num, 3); + num = low_sign_unext (num, 14); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); } - else + break; + + /* Handle a 16 bit immediate at 31. */ + case '<': + the_insn.field_selector = pa_chk_field_selector (&s); + get_expression (s); + s = expr_end; + if (the_insn.exp.X_op == O_constant) { - break; + int mb; + + mb = opcode & 1; + opcode -= mb; + num = evaluate_absolute (&the_insn); + if (mb != (num < 0)) + break; + CHECK_FIELD (num, 32767, -32768, 0); + num = re_assemble_16 (num); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + } + break; + + /* Handle a 16 bit immediate at 31. */ + case '>': + the_insn.field_selector = pa_chk_field_selector (&s); + get_expression (s); + s = expr_end; + if (the_insn.exp.X_op == O_constant) + { + int mb; + + mb = opcode & 1; + opcode -= mb; + num = evaluate_absolute (&the_insn); + if (mb == (num < 0)) + break; + if (num % 4) + break; + CHECK_FIELD (num, 32767, -32768, 0); + num = re_assemble_16 (num); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); } + break; /* Handle 14 bit immediate, shifted left three times. */ case '#': diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 4632f75208..9878734d73 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,10 @@ +2001-01-14 Alan Modra + + * hppa.h: Describe new '<' and '>' operand types, and tidy + existing comments. + (pa_opcodes): Add entries for missing wide mode ldi,ldo,ldw,stw. + Remove duplicate "ldw j(s,b),x". Sort some entries. + Sat Jan 13 09:56:32 MET 2001 Jan Hubicka * i386.h (i386_optab): Fix pusha and ret templates. diff --git a/include/opcode/hppa.h b/include/opcode/hppa.h index f04403d2ee..2ac11e4277 100644 --- a/include/opcode/hppa.h +++ b/include/opcode/hppa.h @@ -1,5 +1,5 @@ /* Table of opcodes for the PA-RISC. - Copyright (C) 1990, 1991, 1993, 1995, 1999, 2000 + Copyright (C) 1990, 1991, 1993, 1995, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by the Center for Software Science at the @@ -71,15 +71,15 @@ struct pa_opcode In the args field, the following characters are unused: - ' " - / 34 6789:;< > @' - ' C M [\] ' - ' e g } ' + ' " - / 34 6789:; ' + '@ C M [\] ' + '` e g } ' Here are all the characters: - ' !"#$%&'()*+-,./0123456789:;<=>?@' - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' - 'abcdefghijklmnopqrstuvwxyz{|}~' + ' !"#$%&'()*+-,./0123456789:;<=>?' + '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' + '`abcdefghijklmnopqrstuvwxyz{|}~ ' Kinds of operands: x integer register field at 15. @@ -147,7 +147,7 @@ Also these: the bb instruction. It's the same as r above, except the value is in a different location) B 5 bit immediate value at 10 (a bit position specified in - the bb instruction. Similar to Q, but 64bit handling is + the bb instruction. Similar to Q, but 64 bit handling is different. Z %r1 -- implicit target of addil instruction. L ,%r2 completer for new syntax branch @@ -155,12 +155,14 @@ Also these: _ Destination format completer for fcnv h cbit for fcmp = gfx tests for ftest - d 14bit offset for single precision FP long load/store. - # 14bit offset for double precision FP load long/store. - J Yet another 14bit offset with an unusual encoding. - K Yet another 14bit offset with an unusual encoding. - y 16bit offset for single precision FP long load/store (PA2.0 wide). - & 16bit offset for double precision FP long load/store (PA2.0 wide). + d 14 bit offset for single precision FP long load/store. + # 14 bit offset for double precision FP load long/store. + J Yet another 14 bit offset for load/store with ma,mb completers. + K Yet another 14 bit offset for load/store with ma,mb completers. + y 16 bit offset for word aligned load/store (PA2.0 wide). + & 16 bit offset for dword aligned load/store (PA2.0 wide). + < 16 bit offset for load/store with ma,mb completers (PA2.0 wide). + > 16 bit offset for load/store with ma,mb completers (PA2.0 wide). Y %sr0,%r31 -- implicit target of be,l instruction. @ implicit immediate value of 0 @@ -279,6 +281,7 @@ static const struct pa_opcode pa_opcodes[] = /* Pseudo-instructions. */ +{ "ldi", 0x34000000, 0xffe00000, "l,x", pa20w, 0},/* ldo val(r0),r */ { "ldi", 0x34000000, 0xffe0c000, "j,x", pa10, 0},/* ldo val(r0),r */ { "call", 0xe800f000, 0xfc1ffffd, "n(b)", pa20, FLAG_STRICT}, @@ -321,36 +324,37 @@ static const struct pa_opcode pa_opcodes[] = { "ldd", 0x0c0010c0, 0xfc0013c0, "cmcc5(b),t", pa20, FLAG_STRICT}, { "ldd", 0x50000000, 0xfc000002, "cq&(b),x", pa20w, FLAG_STRICT}, { "ldd", 0x50000000, 0xfc000002, "cq#(b),x", pa20, FLAG_STRICT}, -{ "ldw", 0x48000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT}, { "ldw", 0x0c000080, 0xfc0013c0, "cxccx(s,b),t", pa10, FLAG_STRICT}, { "ldw", 0x0c000080, 0xfc0013c0, "cxccx(b),t", pa10, FLAG_STRICT}, { "ldw", 0x0c0010a0, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT}, { "ldw", 0x0c0010a0, 0xfc1f33e0, "cocc@(b),t", pa20, FLAG_STRICT}, { "ldw", 0x0c001080, 0xfc0013c0, "cmcc5(s,b),t", pa10, FLAG_STRICT}, { "ldw", 0x0c001080, 0xfc0013c0, "cmcc5(b),t", pa10, FLAG_STRICT}, +{ "ldw", 0x4c000000, 0xfc000000, "ce<(b),x", pa20w, FLAG_STRICT}, { "ldw", 0x4c000000, 0xfc000000, "ceJ(s,b),x", pa10, FLAG_STRICT}, { "ldw", 0x4c000000, 0xfc000000, "ceJ(b),x", pa10, FLAG_STRICT}, +{ "ldw", 0x5c000004, 0xfc000006, "ce>(b),x", pa20w, FLAG_STRICT}, { "ldw", 0x5c000004, 0xfc000006, "ceK(s,b),x", pa20, FLAG_STRICT}, { "ldw", 0x5c000004, 0xfc000006, "ceK(b),x", pa20, FLAG_STRICT}, -{ "ldw", 0x48000000, 0xfc000000, "j(s,b),x", pa10, 0}, +{ "ldw", 0x48000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT}, { "ldw", 0x48000000, 0xfc000000, "j(s,b),x", pa10, 0}, { "ldw", 0x48000000, 0xfc000000, "j(b),x", pa10, 0}, -{ "ldh", 0x44000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT}, { "ldh", 0x0c000040, 0xfc0013c0, "cxccx(s,b),t", pa10, FLAG_STRICT}, { "ldh", 0x0c000040, 0xfc0013c0, "cxccx(b),t", pa10, FLAG_STRICT}, { "ldh", 0x0c001060, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT}, { "ldh", 0x0c001060, 0xfc1f33e0, "cocc@(b),t", pa20, FLAG_STRICT}, { "ldh", 0x0c001040, 0xfc0013c0, "cmcc5(s,b),t", pa10, FLAG_STRICT}, { "ldh", 0x0c001040, 0xfc0013c0, "cmcc5(b),t", pa10, FLAG_STRICT}, +{ "ldh", 0x44000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT}, { "ldh", 0x44000000, 0xfc000000, "j(s,b),x", pa10, 0}, { "ldh", 0x44000000, 0xfc000000, "j(b),x", pa10, 0}, -{ "ldb", 0x40000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT}, { "ldb", 0x0c000000, 0xfc0013c0, "cxccx(s,b),t", pa10, FLAG_STRICT}, { "ldb", 0x0c000000, 0xfc0013c0, "cxccx(b),t", pa10, FLAG_STRICT}, { "ldb", 0x0c001020, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT}, { "ldb", 0x0c001020, 0xfc1f33e0, "cocc@(b),t", pa20, FLAG_STRICT}, { "ldb", 0x0c001000, 0xfc0013c0, "cmcc5(s,b),t", pa10, FLAG_STRICT}, { "ldb", 0x0c001000, 0xfc0013c0, "cmcc5(b),t", pa10, FLAG_STRICT}, +{ "ldb", 0x40000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT}, { "ldb", 0x40000000, 0xfc000000, "j(s,b),x", pa10, 0}, { "ldb", 0x40000000, 0xfc000000, "j(b),x", pa10, 0}, { "std", 0x0c0012e0, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT}, @@ -359,29 +363,31 @@ static const struct pa_opcode pa_opcodes[] = { "std", 0x0c0012c0, 0xfc0013c0, "cmcCx,V(b)", pa20, FLAG_STRICT}, { "std", 0x70000000, 0xfc000002, "cqx,&(b)", pa20w, FLAG_STRICT}, { "std", 0x70000000, 0xfc000002, "cqx,#(b)", pa20, FLAG_STRICT}, -{ "stw", 0x68000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT}, { "stw", 0x0c0012a0, 0xfc0013ff, "cocCx,@(s,b)", pa20, FLAG_STRICT}, { "stw", 0x0c0012a0, 0xfc0013ff, "cocCx,@(b)", pa20, FLAG_STRICT}, { "stw", 0x0c001280, 0xfc0013c0, "cmcCx,V(s,b)", pa10, FLAG_STRICT}, { "stw", 0x0c001280, 0xfc0013c0, "cmcCx,V(b)", pa10, FLAG_STRICT}, +{ "stw", 0x6c000000, 0xfc000000, "cex,<(b)", pa20w, FLAG_STRICT}, { "stw", 0x6c000000, 0xfc000000, "cex,J(s,b)", pa10, FLAG_STRICT}, { "stw", 0x6c000000, 0xfc000000, "cex,J(b)", pa10, FLAG_STRICT}, +{ "stw", 0x7c000004, 0xfc000006, "cex,>(b)", pa20w, FLAG_STRICT}, { "stw", 0x7c000004, 0xfc000006, "cex,K(s,b)", pa20, FLAG_STRICT}, { "stw", 0x7c000004, 0xfc000006, "cex,K(b)", pa20, FLAG_STRICT}, +{ "stw", 0x68000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT}, { "stw", 0x68000000, 0xfc000000, "x,j(s,b)", pa10, 0}, { "stw", 0x68000000, 0xfc000000, "x,j(b)", pa10, 0}, -{ "sth", 0x64000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT}, { "sth", 0x0c001260, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT}, { "sth", 0x0c001260, 0xfc0033ff, "cocCx,@(b)", pa20, FLAG_STRICT}, { "sth", 0x0c001240, 0xfc0013c0, "cmcCx,V(s,b)", pa10, FLAG_STRICT}, { "sth", 0x0c001240, 0xfc0013c0, "cmcCx,V(b)", pa10, FLAG_STRICT}, +{ "sth", 0x64000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT}, { "sth", 0x64000000, 0xfc000000, "x,j(s,b)", pa10, 0}, { "sth", 0x64000000, 0xfc000000, "x,j(b)", pa10, 0}, -{ "stb", 0x60000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT}, { "stb", 0x0c001220, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT}, { "stb", 0x0c001220, 0xfc0033ff, "cocCx,@(b)", pa20, FLAG_STRICT}, { "stb", 0x0c001200, 0xfc0013c0, "cmcCx,V(s,b)", pa10, FLAG_STRICT}, { "stb", 0x0c001200, 0xfc0013c0, "cmcCx,V(b)", pa10, FLAG_STRICT}, +{ "stb", 0x60000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT}, { "stb", 0x60000000, 0xfc000000, "x,j(s,b)", pa10, 0}, { "stb", 0x60000000, 0xfc000000, "x,j(b)", pa10, 0}, { "ldwm", 0x4c000000, 0xfc000000, "j(s,b),x", pa10, 0}, @@ -439,6 +445,7 @@ static const struct pa_opcode pa_opcodes[] = { "stbys", 0x0c001300, 0xfc001fc0, "csx,V(b)", pa10, 0}, /* Immediate instructions. */ +{ "ldo", 0x34000000, 0xfc000000, "l(b),x", pa20w, 0}, { "ldo", 0x34000000, 0xfc00c000, "j(b),x", pa10, 0}, { "ldil", 0x20000000, 0xfc000000, "k,b", pa10, 0}, { "addil", 0x28000000, 0xfc000000, "k,b,Z", pa10, 0}, diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index e118c0effa..5609161288 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,7 @@ +2001-01-14 Alan Modra + + * hppa-dis.c (print_insn_hppa): Handle '>' and '<' arg types. + 2001-01-13 Nick Clifton * disassemble.c: Remove spurious white space. diff --git a/opcodes/hppa-dis.c b/opcodes/hppa-dis.c index 1312bc5342..7fda0f2db0 100644 --- a/opcodes/hppa-dis.c +++ b/opcodes/hppa-dis.c @@ -1,5 +1,5 @@ /* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c. - Copyright 1989, 90, 92, 93, 94, 95, 98, 99, 2000 + Copyright 1989, 90, 92, 93, 94, 95, 98, 99, 2000, 2001 Free Software Foundation, Inc. Contributed by the Center for Software Science at the @@ -889,6 +889,7 @@ print_insn_hppa (memaddr, info) case 'k': fput_const (extract_21 (insn), info); break; + case '<': case 'l': /* 16-bit long disp., PA2.0 wide only. */ fput_const (extract_16 (insn), info); @@ -1099,6 +1100,7 @@ print_insn_hppa (memaddr, info) break; } + case '>': case 'y': { /* 16-bit long disp., PA2.0 wide only. */ -- 2.34.1