Commit fd3f89a9 by Torbjorn Granlund

(comment before extendhisi2): Remove the lie.

(zero_extendhisi2): Rewrite to work if op0 == op1.  Use
gen_lowpart in preparation code.
(extendqisi2, extendhisi2): Likewise.
(extendqihi2): Expand.
(restorehi): Rewrite for correctness, efficiency, and
clarity. Avoid generating insns involving truncate.  Generate
needed pseudos in preparation statements.
(storehi): Likewise.
(storeinthi): Likewise.
(movhi): Call gen_storehi, gen_restorehi, gen_storeinthi according
their new definitions.  Use force_reg to put address in register.

From-SVN: r2255
parent 57cdc6c2
......@@ -484,19 +484,16 @@
;; Zero extension instructions.
(define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
[(set (match_dup 2)
(ashift:SI (match_operand:HI 1 "register_operand" "")
(const_int 16)))
(set (match_dup 0)
(lshiftrt:SI (match_dup 0) (const_int 16)))]
(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI (match_dup 2)
(const_int 16)))]
""
"
if (GET_CODE (operands[1]) == SUBREG)
operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
SUBREG_WORD (operands[1]));
else
operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
")
{ operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_reg_rtx (SImode); }")
(define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r")
......@@ -522,51 +519,42 @@
}
")
;; Note that the ones starting from HImode come before those for QImode so
;; that a constant operand will match HImode, not QImode.
(define_expand "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
[(set (match_dup 2)
(ashift:SI (match_operand:HI 1 "register_operand" "")
(const_int 16)))
(set (match_dup 0)
(ashiftrt:SI (match_dup 0) (const_int 16)))]
(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (match_dup 2)
(const_int 16)))]
""
"
if (GET_CODE (operands[1]) == SUBREG)
operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
SUBREG_WORD (operands[1]));
else
operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
")
;; XXX Is this ever used?
{ operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_reg_rtx (SImode); }")
(define_insn "extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r")
(sign_extend:SI
(match_operand:QI 1 "register_operand" "r")))]
(define_expand "extendqihi2"
[(set (match_dup 2)
(ashift:SI (match_operand:QI 1 "register_operand" "")
(const_int 24)))
(set (match_operand:HI 0 "register_operand" "")
(ashiftrt:SI (match_dup 2)
(const_int 24)))]
""
"*
arm_output_asm_insn (\"mov\\t%0, %1, lsl#24\\t@ extendqihi\", operands);
return (arm_output_asm_insn (\"mov\\t%0, %0, asr#24\", operands));
")
"
{ operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_reg_rtx (SImode); }")
(define_expand "extendqisi2"
[(set (match_operand:SI 0 "register_operand" "")
[(set (match_dup 2)
(ashift:SI (match_operand:QI 1 "register_operand" "")
(const_int 24)))
(set (match_dup 0)
(ashiftrt:SI (match_dup 0) (const_int 24)))]
(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (match_dup 2)
(const_int 24)))]
""
"
if (GET_CODE (operands[1]) == SUBREG)
operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
SUBREG_WORD(operands[1]));
else
operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
")
{ operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_reg_rtx (SImode); }")
(define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
......@@ -698,73 +686,55 @@
;; storehi is not allowed.
(define_expand "restorehi"
[(set (mem:QI (match_operand:SI 1 "address_operand" ""))
(truncate:QI (match_operand:HI 0 "register_operand" "")))
(set (reg:HI 10)
(ashiftrt:HI (match_dup 0) (const_int 8)))
[(set (mem:QI (match_operand 1 "" ""))
(match_dup 2))
(set (reg:SI 10)
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
(set (mem:QI (plus:SI (match_dup 1) (const_int 1)))
(truncate:QI (reg:HI 10)))]
"" "")
(reg:QI 10))]
""
"
{
operands[2] = gen_lowpart (QImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
}")
;; Subroutine to store a half word from a register into memory.
;; Operand 0 is the source register (HImode)
;; Operand 1 is the destination address (SImode)
;; Operand 2 is a temporary (SImode).
;; Operand 3 is a temporary (SImode).
;; Operand 4 is a temporary (SImode).
;; Operand 1 is the destination address in a register (SImode)
(define_expand "storehi"
[;; compute the address into a register
(set (match_operand:SI 2 "register_operand" "")
(match_operand:SI 1 "address_operand" ""))
;; get the half word into a full word register
(set (match_operand:SI 3 "register_operand" "")
(match_operand:HI 0 "register_operand" ""))
;; store the low byte
(set (mem:QI (match_dup 2))
(truncate:QI (match_dup 3)))
[;; store the low byte
(set (mem:QI (match_operand 1 "" "")) (match_dup 3))
;; extract the high byte
(set (match_operand:SI 4 "register_operand" "")
(ashiftrt:SI (match_dup 3) (const_int 8)))
(set (match_dup 2)
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
;; store the high byte
(set (mem:QI (plus (match_dup 2) (const_int 1)))
(truncate:QI (match_dup 4)))]
(set (mem:QI (plus (match_dup 1) (const_int 1)))
(subreg:QI (match_dup 2) 0))] ;explicit subreg safe
""
"
{ operands[3] = gen_lowpart (QImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
")
operands[2] = gen_reg_rtx (SImode); }")
;; Subroutine to store a half word integer constant into memory.
;; Operand 0 is the constant
;; Operand 1 is the destination address (SImode)
;; Operand 2 is a temporary (SImode).
;; Operand 3 is a temporary (QImode).
;; Operand 4 is a temporary (QImode).
;; Operand 5 is a local CONST_INT.
;; Operand 1 is the destination address in a register (SImode)
(define_expand "storeinthi"
[;; compute the address into a register
(set (match_operand:SI 2 "register_operand" "")
(match_operand:SI 1 "address_operand" ""))
;; load the low byte
(set (match_operand:QI 3 "register_operand" "")
(match_operand:SI 0 "" ""))
;; store the low byte
(set (mem:QI (match_dup 2))
(match_dup 3))
;; load the high byte
(set (match_operand:QI 4 "register_operand" "")
(match_dup 5))
[;; store the low byte
(set (mem:QI (match_operand 1 "" "")) (match_operand 0 "" ""))
;; store the high byte
(set (mem:QI (plus (match_dup 2) (const_int 1)))
(match_dup 4))]
(set (mem:QI (plus (match_dup 1) (const_int 1)))
(match_dup 2))]
""
"
{
int value = INTVAL(operands[0]);
int value = INTVAL (operands[0]);
operands[0] = gen_rtx(CONST_INT, VOIDmode, value & 255);
operands[5] = gen_rtx(CONST_INT, VOIDmode,(value>>8) & 255);
operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
operands[2] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
}
")
......@@ -787,22 +757,15 @@
{
if (GET_CODE (operands[0]) == MEM)
{
if (GET_CODE (operands[1]) == MEM)
operands[1] = copy_to_reg (operands[1]);
if (GET_CODE (operands[1]) == CONST_INT)
{
insn = gen_storeinthi (operands[1], XEXP (operands[0], 0),
gen_reg_rtx (SImode),
gen_reg_rtx (QImode),
gen_reg_rtx (QImode));
insn = gen_storeinthi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
}
else
{
insn = gen_storehi (operands[1], XEXP (operands[0], 0),
gen_reg_rtx (SImode),
gen_reg_rtx (SImode),
gen_reg_rtx (SImode));
if (GET_CODE (operands[1]) == MEM)
operands[1] = copy_to_reg (operands[1]);
insn = gen_storehi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
}
}
#if 0
......@@ -852,7 +815,6 @@
case 3:
return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
}
")
(define_insn "movsf"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment