From 91c2f09e6b0b8bf4ad2bb872b5748b7d1fd5826a Mon Sep 17 00:00:00 2001 From: Dave Anglin Date: Tue, 24 Feb 2009 23:48:57 +0000 Subject: [PATCH] * gas/config/tc-hppa.c (pa_ip): Add check of immediate values. (SAVE_IMMEDIATE): New define. --- gas/ChangeLog | 5 +++++ gas/config/tc-hppa.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index c1207bd9a90..fd3308be7b4 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2009-02-24 Helge Deller + + * gas/config/tc-hppa.c (pa_ip): Add check of immediate values. + (SAVE_IMMEDIATE): New define. + 2009-02-23 Mark Mitchell * config/tc-arm.c (warn_deprecated_sp): New macro. diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 7bb7966141f..1393a7c581e 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -1,6 +1,6 @@ /* tc-hppa.c -- Assemble for the PA - Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -995,6 +995,19 @@ static struct default_space_dict pa_def_spaces[] = #define IS_R_SELECT(S) (*(S) == 'R' || *(S) == 'r') #define IS_L_SELECT(S) (*(S) == 'L' || *(S) == 'l') +/* Store immediate values of shift/deposit/extract functions. */ + +#define SAVE_IMMEDIATE(VALUE) \ + { \ + if (immediate_check) \ + { \ + if (pos == -1) \ + pos = (VALUE); \ + else if (len == -1) \ + len = (VALUE); \ + } \ + } + /* Insert FIELD into OPCODE starting at bit START. Continue pa_ip main loop after insertion. */ @@ -3191,6 +3204,7 @@ pa_ip (char *str) int match = FALSE; int comma = 0; int cmpltr, nullif, flag, cond, num; + int immediate_check = 0, pos = -1, len = -1; unsigned long opcode; struct pa_opcode *insn; @@ -3351,6 +3365,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 32, 1, 0); + SAVE_IMMEDIATE(num); INSERT_FIELD_AND_CONTINUE (opcode, 32 - num, 0); /* Handle a 5 bit immediate at 15. */ @@ -4333,6 +4348,9 @@ pa_ip (char *str) case 'x': case 'y': cmpltr = 0; + /* Check immediate values in shift/extract/deposit + * instructions if they will give undefined behaviour. */ + immediate_check = 1; if (*s == ',') { save_s = s++; @@ -5125,6 +5143,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 31, 0, strict); + SAVE_IMMEDIATE(num); INSERT_FIELD_AND_CONTINUE (opcode, 31 - num, 5); /* Handle a 6 bit shift count at 20,22:26. */ @@ -5134,6 +5153,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 63, 0, strict); + SAVE_IMMEDIATE(num); num = 63 - num; opcode |= (num & 0x20) << 6; INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5); @@ -5146,6 +5166,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 64, 1, strict); + SAVE_IMMEDIATE(num); num--; opcode |= (num & 0x20) << 3; num = 31 - (num & 0x1f); @@ -5158,6 +5179,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 64, 1, strict); + SAVE_IMMEDIATE(num); num--; opcode |= (num & 0x20) << 7; num = 31 - (num & 0x1f); @@ -5170,6 +5192,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 31, 0, strict); + SAVE_IMMEDIATE(num); INSERT_FIELD_AND_CONTINUE (opcode, num, 5); /* Handle a 6 bit bit position at 20,22:26. */ @@ -5179,6 +5202,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 63, 0, strict); + SAVE_IMMEDIATE(num); opcode |= (num & 0x20) << 6; INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5); @@ -5686,6 +5710,13 @@ pa_ip (char *str) break; } + if (immediate_check) + { + if (pos != -1 && len != -1 && pos < len - 1) + as_warn (_("Immediates %d and %d will give undefined behavior."), + pos, len); + } + the_insn.opcode = opcode; } -- 2.30.2