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 @@ ...@@ -484,19 +484,16 @@
;; Zero extension instructions. ;; Zero extension instructions.
(define_expand "zero_extendhisi2" (define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_dup 2)
(ashift:SI (match_operand:HI 1 "register_operand" "") (ashift:SI (match_operand:HI 1 "register_operand" "")
(const_int 16))) (const_int 16)))
(set (match_dup 0) (set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI (match_dup 0) (const_int 16)))] (lshiftrt:SI (match_dup 2)
(const_int 16)))]
"" ""
" "
if (GET_CODE (operands[1]) == SUBREG) { operands[1] = gen_lowpart (SImode, operands[1]);
operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]), operands[2] = gen_reg_rtx (SImode); }")
SUBREG_WORD (operands[1]));
else
operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
")
(define_insn "zero_extendqihi2" (define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
...@@ -522,51 +519,42 @@ ...@@ -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" (define_expand "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_dup 2)
(ashift:SI (match_operand:HI 1 "register_operand" "") (ashift:SI (match_operand:HI 1 "register_operand" "")
(const_int 16))) (const_int 16)))
(set (match_dup 0) (set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (match_dup 0) (const_int 16)))] (ashiftrt:SI (match_dup 2)
(const_int 16)))]
"" ""
" "
if (GET_CODE (operands[1]) == SUBREG) { operands[1] = gen_lowpart (SImode, operands[1]);
operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]), operands[2] = gen_reg_rtx (SImode); }")
SUBREG_WORD (operands[1]));
else
operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
")
;; XXX Is this ever used?
(define_insn "extendqihi2" (define_expand "extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_dup 2)
(sign_extend:SI (ashift:SI (match_operand:QI 1 "register_operand" "")
(match_operand:QI 1 "register_operand" "r")))] (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); { operands[0] = gen_lowpart (SImode, operands[0]);
return (arm_output_asm_insn (\"mov\\t%0, %0, asr#24\", operands)); operands[1] = gen_lowpart (SImode, operands[1]);
") operands[2] = gen_reg_rtx (SImode); }")
(define_expand "extendqisi2" (define_expand "extendqisi2"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_dup 2)
(ashift:SI (match_operand:QI 1 "register_operand" "") (ashift:SI (match_operand:QI 1 "register_operand" "")
(const_int 24))) (const_int 24)))
(set (match_dup 0) (set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (match_dup 0) (const_int 24)))] (ashiftrt:SI (match_dup 2)
(const_int 24)))]
"" ""
" "
if (GET_CODE (operands[1]) == SUBREG) { operands[1] = gen_lowpart (SImode, operands[1]);
operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]), operands[2] = gen_reg_rtx (SImode); }")
SUBREG_WORD(operands[1]));
else
operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
")
(define_insn "extendsfdf2" (define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=f") [(set (match_operand:DF 0 "register_operand" "=f")
...@@ -698,73 +686,55 @@ ...@@ -698,73 +686,55 @@
;; storehi is not allowed. ;; storehi is not allowed.
(define_expand "restorehi" (define_expand "restorehi"
[(set (mem:QI (match_operand:SI 1 "address_operand" "")) [(set (mem:QI (match_operand 1 "" ""))
(truncate:QI (match_operand:HI 0 "register_operand" ""))) (match_dup 2))
(set (reg:HI 10) (set (reg:SI 10)
(ashiftrt:HI (match_dup 0) (const_int 8))) (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
(set (mem:QI (plus:SI (match_dup 1) (const_int 1))) (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. ;; Subroutine to store a half word from a register into memory.
;; Operand 0 is the source register (HImode) ;; Operand 0 is the source register (HImode)
;; Operand 1 is the destination address (SImode) ;; Operand 1 is the destination address in a register (SImode)
;; Operand 2 is a temporary (SImode).
;; Operand 3 is a temporary (SImode).
;; Operand 4 is a temporary (SImode).
(define_expand "storehi" (define_expand "storehi"
[;; compute the address into a register [;; store the low byte
(set (match_operand:SI 2 "register_operand" "") (set (mem:QI (match_operand 1 "" "")) (match_dup 3))
(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)))
;; extract the high byte ;; extract the high byte
(set (match_operand:SI 4 "register_operand" "") (set (match_dup 2)
(ashiftrt:SI (match_dup 3) (const_int 8))) (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
;; store the high byte ;; store the high byte
(set (mem:QI (plus (match_dup 2) (const_int 1))) (set (mem:QI (plus (match_dup 1) (const_int 1)))
(truncate:QI (match_dup 4)))] (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
"" ""
" "
{ operands[3] = gen_lowpart (QImode, operands[0]);
operands[0] = gen_lowpart (SImode, 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. ;; Subroutine to store a half word integer constant into memory.
;; Operand 0 is the constant ;; Operand 0 is the constant
;; Operand 1 is the destination address (SImode) ;; Operand 1 is the destination address in a register (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.
(define_expand "storeinthi" (define_expand "storeinthi"
[;; compute the address into a register [;; store the low byte
(set (match_operand:SI 2 "register_operand" "") (set (mem:QI (match_operand 1 "" "")) (match_operand 0 "" ""))
(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 high byte ;; store the high byte
(set (mem:QI (plus (match_dup 2) (const_int 1))) (set (mem:QI (plus (match_dup 1) (const_int 1)))
(match_dup 4))] (match_dup 2))]
"" ""
" "
{ {
int value = INTVAL(operands[0]); int value = INTVAL (operands[0]);
operands[0] = gen_rtx(CONST_INT, VOIDmode, value & 255); operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
operands[5] = gen_rtx(CONST_INT, VOIDmode,(value>>8) & 255); operands[2] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
} }
") ")
...@@ -787,22 +757,15 @@ ...@@ -787,22 +757,15 @@
{ {
if (GET_CODE (operands[0]) == MEM) 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) if (GET_CODE (operands[1]) == CONST_INT)
{ {
insn = gen_storeinthi (operands[1], XEXP (operands[0], 0), insn = gen_storeinthi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
gen_reg_rtx (SImode),
gen_reg_rtx (QImode),
gen_reg_rtx (QImode));
} }
else else
{ {
insn = gen_storehi (operands[1], XEXP (operands[0], 0), if (GET_CODE (operands[1]) == MEM)
gen_reg_rtx (SImode), operands[1] = copy_to_reg (operands[1]);
gen_reg_rtx (SImode), insn = gen_storehi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
gen_reg_rtx (SImode));
} }
} }
#if 0 #if 0
...@@ -852,7 +815,6 @@ ...@@ -852,7 +815,6 @@
case 3: case 3:
return (arm_output_asm_insn (\"strb\\t%1, %0\", operands)); return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
} }
") ")
(define_insn "movsf" (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