This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [Patch - hppa] add compile time check for immediate values of shift/deposit/extract
- From: Helge Deller <deller at gmx dot de>
- To: John David Anglin <dave at hiauly1 dot hia dot nrc dot ca>
- Cc: binutils at sourceware dot org, dave dot anglin at nrc dot ca, amodra at bigpond dot net dot au
- Date: Sun, 22 Feb 2009 21:16:20 +0100
- Subject: Re: [Patch - hppa] add compile time check for immediate values of shift/deposit/extract
- References: <20090222194027.C98BE4EE5@hiauly1.hia.nrc.ca>
John David Anglin wrote:
> Helge Deller wrote:
>> The patch below adds compile time checks to gas which (where possible)
>> will check the constant immediate values of the shift/deposit/extract
>> functions and warn the user if he coded a dangerous combination.
>
> This is a good idea.
> This can be improved.
> [....]
Thanks for those suggestions!
Here is an updated version of the patch.
2009-02-22 Helge Deller <deller@gmx.de>
* gas/config/tc-hppa.c (pa_ip): add check of immediate values,
(SAVE_IMMEDIATE): new #define
Index: gas/config/tc-hppa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-hppa.c,v
retrieving revision 1.142
diff -u -p -r1.142 tc-hppa.c
--- gas/config/tc-hppa.c 9 Sep 2008 00:53:35 -0000 1.142
+++ gas/config/tc-hppa.c 22 Feb 2009 19:56:45 -0000
@@ -995,6 +995,20 @@ static struct default_space_dict pa_def_
#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 +3205,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 +3366,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 +4349,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 +5144,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 +5154,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 +5167,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 +5180,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 +5193,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 +5203,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 +5711,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;
}