\f
;; zero extension instructions
+(define_insn "zero_extendqidi2"
+ [(set (match_operand:DI 0 "general_operand" "=&d")
+ (zero_extend:DI (match_operand:QI 1 "general_operand" "dm")))]
+ ""
+ "*
+{
+ CC_STATUS_INIT;
+ operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ return \"moveq %#0,%0\;moveq %#0,%2\;move%.b %1,%2\";
+}")
+
+(define_insn "zero_extendhidi2"
+ [(set (match_operand:DI 0 "general_operand" "=&d")
+ (zero_extend:DI (match_operand:HI 1 "general_operand" "rm")))]
+ ""
+ "*
+{
+ CC_STATUS_INIT;
+ operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ return \"moveq %#0,%0\;moveq %#0,%2\;move%.w %1,%2\";
+}")
+
;; this is the canonical form for (lshiftrt:DI x 32)
(define_insn "zero_extendsidi2"
[(set (match_operand:DI 0 "general_operand" "rm")
return \"clr%.l %0\;move%.l %1,%0\";
else
operands[2] = adj_offsettable_operand (operands[0], 4);
+ if (GET_CODE (operands[1]) != REG || GET_CODE (operands[1]) != REG
+ || REGNO (operands[1]) != REGNO (operands[2]))
+ output_asm_insn (\"move%.l %1,%2\", operands);
if (ADDRESS_REG_P (operands[0]))
- return \"move%.l %1,%2\;sub%.l %0,%0\";
+ return \"sub%.l %0,%0\";
else
- return \"move%.l %1,%2\;clr%.l %0\";
+ return \"clr%.l %0\";
}")
(define_expand "zero_extendhisi2"
\f
;; inclusive-or instructions
+(define_insn "iordi_zext"
+ [(set (match_operand:DI 0 "general_operand" "=o,d")
+ (ior:DI (zero_extend:DI (match_operand 1 "general_operand" "dn,dmn"))
+ (match_operand:DI 2 "general_operand" "0,0")))]
+ "!TARGET_5200"
+ "*
+{
+ int byte_mode;
+
+ CC_STATUS_INIT;
+ if (GET_CODE (operands[0]) == REG)
+ operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ else
+ operands[0] = adj_offsettable_operand (operands[0], 4);
+ if (GET_MODE (operands[1]) == SImode)
+ return \"or%.l %1,%0\";
+ byte_mode = (GET_MODE (operands[1]) == QImode);
+ if (GET_CODE (operands[0]) == MEM)
+ operands[0] = adj_offsettable_operand (operands[0], byte_mode ? 3 : 2);
+ if (byte_mode)
+ return \"or%.b %1,%0\";
+ else
+ return \"or%.w %1,%0\";
+}")
+
;; "iordi3" is mainly here to help combine().
(define_insn "iordi3"
[(set (match_operand:DI 0 "general_operand" "=o,d")
;; On all 68k models, this makes faster code in a special case.
;; See also ashlsi_16, ashrsi_16 and lshrsi_16.
-;; ??? This pattern can not work as written, because it fails if operand 0
-;; and operand 1 are the same register. This can happen for alternative 1.
-;; This will still fail even if an early clobber is added to the output
-;; for alternative 1. This is because reload may satisfy the matching
-;; constraint by forcing the output to use exactly the same register as
-;; operand 2, without noticing that this then causes a conflict with operand 1.
-;; Possible fix: check for operand 0/1 overlap, and emit correct but slower
-;; code. This should be rare if the early clobber is added.
-
(define_insn "iorsi_zexthi_ashl16"
- [(set (match_operand:SI 0 "general_operand" "=&d,d")
- (ior:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "dmn,dmn"))
- (ashift:SI (match_operand:SI 2 "general_operand" "o,0")
+ [(set (match_operand:SI 0 "general_operand" "=&d")
+ (ior:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rmn"))
+ (ashift:SI (match_operand:SI 2 "general_operand" "or")
(const_int 16))))]
- "0"
+ ""
"*
{
CC_STATUS_INIT;
if (GET_CODE (operands[2]) != REG)
- {
operands[2] = adj_offsettable_operand (operands[2], 2);
- output_asm_insn (\"move%.w %2,%0\", operands);
- }
+ if (GET_CODE (operands[2]) != REG
+ || REGNO (operands[2]) != REGNO (operands[0]))
+ output_asm_insn (\"move%.w %2,%0\", operands);
return \"swap %0\;mov%.w %1,%0\";
}")
-(define_insn ""
+(define_insn "iorsi_zext"
[(set (match_operand:SI 0 "general_operand" "=o,d")
(ior:SI (zero_extend:SI (match_operand 1 "general_operand" "dn,dmn"))
(match_operand:SI 2 "general_operand" "0,0")))]
int byte_mode;
CC_STATUS_INIT;
- byte_mode = (GET_MODE(operands[1]) == QImode);
+ byte_mode = (GET_MODE (operands[1]) == QImode);
if (GET_CODE (operands[0]) == MEM)
operands[0] = adj_offsettable_operand (operands[0], byte_mode ? 3 : 2);
if (byte_mode)
- return \"or%.b %1,%0\";
+ return \"or%.b %1,%0\";
else
- return \"or%.w %1,%0\";
+ return \"or%.w %1,%0\";
}")
\f
;; xor instructions