diff options
author | Alan Modra <amodra@bigpond.net.au> | 2001-01-14 05:14:45 +0000 |
---|---|---|
committer | Alan Modra <amodra@bigpond.net.au> | 2001-01-14 05:14:45 +0000 |
commit | 2e02cbadf59ab9fc0f3f3034bd77ef81a4ec443c (patch) | |
tree | 224ea42cc9a2955eadaf0a5eef86469254ebb25e /gas | |
parent | 54a6aac59b32d444f711d0c0210e1d97ca630bb0 (diff) | |
download | binutils-redhat-2e02cbadf59ab9fc0f3f3034bd77ef81a4ec443c.tar.gz |
Adds assembly and dis-assembly support for the HPPA wide
mode, 16 bit forms of ldi, ldo, ldw and stw instructions.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/tc-hppa.c | 89 |
2 files changed, 64 insertions, 31 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 <alan@linuxcare.com.au> + + * 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 <jh@suse.cz> * 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 '#': |