* mn10300.c (const_8bit_operand): New function.
(mask_ok_for_mem_btst): New funtion.
* mn10300.md (btst patterns with mem operands): Use new functions
to avoid creating btst instructions with invalid operands.
From-SVN: r16236
+Thu Oct 30 13:26:12 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.c (const_8bit_operand): New function.
+ (mask_ok_for_mem_btst): New funtion.
+ * mn10300.md (btst patterns with mem operands): Use new functions
+ to avoid creating btst instructions with invalid operands.
+
Wed Oct 29 16:57:19 1997 Michael Meissner <meissner@cygnus.com>
* rs6000/xm-sysv4.h: Include xm-linux.h instead of xm-svr4.h if we
return 0;
}
+/* Return 1 if X is a CONST_INT that is only 8 bits wide. This is used
+ for the btst insn which may examine memory or a register (the memory
+ variant only allows an unsigned 8 bit integer). */
+int
+const_8bit_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+{
+ return (GET_CODE (op) == CONST_INT
+ && INTVAL (op) >= 0
+ && INTVAL (op) < 256);
+}
+
+/* Similarly, but when using a zero_extract pattern for a btst where
+ the source operand might end up in memory. */
+int
+mask_ok_for_mem_btst (len, bit)
+ int len;
+ int bit;
+{
+ int mask = 0;
+
+ while (len > 0)
+ {
+ mask |= (1 << bit);
+ bit++;
+ len--;
+ }
+
+ /* MASK must bit into an 8bit value. */
+ return (((mask & 0xff) == mask)
+ || ((mask & 0xff00) == mask)
+ || ((mask & 0xff0000) == mask)
+ || ((mask & 0xff000000) == mask));
+}
+
/* Return 1 if X contains a symbolic expression. We know these
expressions will have one of a few well defined forms, so
we need only check those forms. */
(zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
(match_operand 1 "const_int_operand" "")
(match_operand 2 "const_int_operand" "")))]
- "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
+ "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
"*
{
int len = INTVAL (operands[1]);
len--;
}
+ /* If the source operand is not a reg (ie it is memory), then extract the
+ bits from mask that we actually want to test. Note that the mask will
+ never cross a byte boundary. */
+ if (!REG_P (operands[0]))
+ {
+ if (mask & 0xff)
+ mask = mask & 0xff;
+ else if (mask & 0xff00)
+ mask = (mask >> 8) & 0xff;
+ else if (mask & 0xff0000)
+ mask = (mask >> 16) & 0xff;
+ else if (mask & 0xff000000)
+ mask = (mask >> 24) & 0xff;
+ }
+
xoperands[0] = operands[0];
xoperands[1] = GEN_INT (mask);
if (GET_CODE (operands[0]) == REG)
[(set (cc0)
(and:SI
(subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
- (match_operand:SI 1 "const_int_operand" "")))]
+ (match_operand:SI 1 "const_8bit_operand" "")))]
""
"@
btst %1,%A0