From: Jeffrey A Law Date: Thu, 30 Oct 1997 20:34:59 +0000 (+0000) Subject: mn10300.c (const_8bit_operand): New function. X-Git-Tag: releases/egcs-1.0.0~205 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f891229781127b313f7d2431175362fbca1e3879;p=thirdparty%2Fgcc.git mn10300.c (const_8bit_operand): New function. * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dd3e2b64046..4af977e8f9ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +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 * rs6000/xm-sysv4.h: Include xm-linux.h instead of xm-svr4.h if we diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index 158cb2b34cdd..201b51d1df22 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -990,6 +990,42 @@ impossible_plus_operand (op, mode) 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. */ diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md index f023478fe14f..1547ad01323d 100644 --- a/gcc/config/mn10300/mn10300.md +++ b/gcc/config/mn10300/mn10300.md @@ -927,7 +927,7 @@ (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]); @@ -942,6 +942,21 @@ 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) @@ -963,7 +978,7 @@ [(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