aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/xtensa/xtensa.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/xtensa/xtensa.md')
-rw-r--r--gcc/config/xtensa/xtensa.md165
1 files changed, 70 insertions, 95 deletions
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 88f011c..629dfdd 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -41,6 +41,8 @@
UNSPEC_LSETUP_START
UNSPEC_LSETUP_END
UNSPEC_FRAME_BLOCKAGE
+ UNSPEC_CEIL
+ UNSPEC_FLOOR
])
(define_c_enum "unspecv" [
@@ -103,6 +105,11 @@
(define_code_attr m_float [(float "float") (unsigned_float "ufloat")])
(define_code_attr s_float [(float "") (unsigned_float "uns")])
+;; This iterator and attribute allow FP-to-integer rounding of two types
+;; to be generated from one template.
+(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR])
+(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")])
+
;; Attributes.
@@ -1007,7 +1014,7 @@
(set_attr "length" "3")])
-;; Field extract instructions.
+;; Field extract and insert instructions.
(define_expand "extvsi"
[(set (match_operand:SI 0 "register_operand" "")
@@ -1141,6 +1148,25 @@
(set_attr "mode" "SI")
(set_attr "length" "6")])
+(define_insn "insvsi"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+a")
+ (match_operand:SI 1 "extui_fldsz_operand" "i")
+ (match_operand:SI 2 "const_int_operand" "i"))
+ (match_operand:SI 3 "register_operand" "r"))]
+ "TARGET_DEPBITS"
+{
+ int shift;
+ if (BITS_BIG_ENDIAN)
+ shift = (32 - (INTVAL (operands[1]) + INTVAL (operands[2]))) & 0x1f;
+ else
+ shift = INTVAL (operands[2]) & 0x1f;
+ operands[2] = GEN_INT (shift);
+ return "depbits\t%0, %3, %2, %1";
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")
+ (set_attr "length" "3")])
+
;; Conversions.
@@ -1168,12 +1194,7 @@
(any_fix:SI (mult:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "fix_scaling_operand" "F"))))]
"TARGET_HARD_FLOAT"
-{
- static char result[64];
- sprintf (result, "<m_fix>.s\t%%0, %%1, %d",
- REAL_EXP (CONST_DOUBLE_REAL_VALUE (operands[2])) - 1);
- return result;
-}
+ "<m_fix>.s\t%0, %1, %U2"
[(set_attr "type" "fconv")
(set_attr "mode" "SF")
(set_attr "length" "3")])
@@ -1192,12 +1213,36 @@
(mult:SF (any_float:SF (match_operand:SI 1 "register_operand" "a"))
(match_operand:SF 2 "float_scaling_operand" "F")))]
"TARGET_HARD_FLOAT"
-{
- static char result[64];
- sprintf (result, "<m_float>.s\t%%0, %%1, %d",
- 1 - REAL_EXP (CONST_DOUBLE_REAL_VALUE (operands[2])));
- return result;
-}
+ "<m_float>.s\t%0, %1, %V2"
+ [(set_attr "type" "fconv")
+ (set_attr "mode" "SF")
+ (set_attr "length" "3")])
+
+(define_insn "l<m_round>sfsi2"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (unspec:SI [(match_operand:SF 1 "register_operand" "f")] ANY_ROUND))]
+ "TARGET_HARD_FLOAT"
+ "<m_round>.s\t%0, %1, 0"
+ [(set_attr "type" "fconv")
+ (set_attr "mode" "SF")
+ (set_attr "length" "3")])
+
+(define_insn "*l<m_round>sfsi2_2x"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (unspec:SI [(plus:SF (match_operand:SF 1 "register_operand" "f")
+ (match_dup 1))] ANY_ROUND))]
+ "TARGET_HARD_FLOAT"
+ "<m_round>.s\t%0, %1, 1"
+ [(set_attr "type" "fconv")
+ (set_attr "mode" "SF")
+ (set_attr "length" "3")])
+
+(define_insn "*l<m_round>sfsi2_scaled"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (unspec:SI [(mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "fix_scaling_operand" "F"))] ANY_ROUND))]
+ "TARGET_HARD_FLOAT"
+ "<m_round>.s\t%0, %1, %U2"
[(set_attr "type" "fconv")
(set_attr "mode" "SF")
(set_attr "length" "3")])
@@ -1252,7 +1297,10 @@
std::swap (operands[0], operands[1]);
std::swap (operands[2], operands[3]);
}
-})
+}
+ [(set_attr "type" "move,move,load,load,store")
+ (set_attr "mode" "DI")
+ (set_attr "length" "6,12,6,6,6")])
(define_split
[(set (match_operand:DI 0 "register_operand")
@@ -1299,7 +1347,7 @@
%v0s32i\t%1, %0
rsr\t%0, ACCLO
wsr\t%1, ACCLO"
- [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
+ [(set_attr "type" "move,move,move,load,store,store,move,move,move,load,move,load,load,store,rsr,wsr")
(set_attr "mode" "SI")
(set_attr "length" "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
@@ -1365,7 +1413,7 @@
%v0s16i\t%1, %0
rsr\t%0, ACCLO
wsr\t%1, ACCLO"
- [(set_attr "type" "move,move,move,move,move,load,load,store,rsr,wsr")
+ [(set_attr "type" "move,move,move,move,load,load,load,store,rsr,wsr")
(set_attr "mode" "HI")
(set_attr "length" "2,2,3,3,3,3,3,3,3,3")])
@@ -1453,7 +1501,7 @@
})
(define_insn "movsf_internal"
- [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,^U,D,a,D,R,a,f,a,a,W,a,U")
+ [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,a,D,R,a,f,a,a,W,a,U")
(match_operand:SF 1 "move_operand" "f,^U,f,d,T,R,d,r,r,f,Y,iF,U,r"))]
"((register_operand (operands[0], SFmode)
|| register_operand (operands[1], SFmode))
@@ -1474,7 +1522,7 @@
const16\t%0, %t1\;const16\t%0, %b1
%v1l32i\t%0, %1
%v0s32i\t%1, %0"
- [(set_attr "type" "farith,fload,fstore,move,load,load,store,move,farith,farith,move,move,load,store")
+ [(set_attr "type" "farith,fload,fstore,move,load,load,store,move,farith,farith,load,move,load,store")
(set_attr "mode" "SF")
(set_attr "length" "3,3,3,2,3,2,2,3,3,3,3,6,3,3")])
@@ -1598,7 +1646,10 @@
std::swap (operands[0], operands[1]);
std::swap (operands[2], operands[3]);
}
-})
+}
+ [(set_attr "type" "move,load,move,load,load,store")
+ (set_attr "mode" "DF")
+ (set_attr "length" "6,6,12,6,6,6")])
;; Block moves
@@ -3319,36 +3370,6 @@
(const_int 8)
(const_int 9))))])
-(define_peephole2
- [(set (match_operand:SI 0 "register_operand")
- (match_operand:SI 6 "reload_operand"))
- (set (match_operand:SI 1 "register_operand")
- (match_operand:SI 7 "reload_operand"))
- (set (match_operand:SF 2 "register_operand")
- (match_operand:SF 4 "register_operand"))
- (set (match_operand:SF 3 "register_operand")
- (match_operand:SF 5 "register_operand"))]
- "REGNO (operands[0]) == REGNO (operands[4])
- && REGNO (operands[1]) == REGNO (operands[5])
- && peep2_reg_dead_p (4, operands[0])
- && peep2_reg_dead_p (4, operands[1])"
- [(set (match_dup 2)
- (match_dup 6))
- (set (match_dup 3)
- (match_dup 7))]
-{
- HARD_REG_SET regs;
- int i;
- CLEAR_HARD_REG_SET (regs);
- for (i = 0; i <= 3; ++i)
- if (TEST_HARD_REG_BIT (regs, REGNO (operands[i])))
- FAIL;
- else
- SET_HARD_REG_BIT (regs, REGNO (operands[i]));
- operands[6] = gen_rtx_MEM (SFmode, XEXP (operands[6], 0));
- operands[7] = gen_rtx_MEM (SFmode, XEXP (operands[7], 0));
-})
-
(define_split
[(clobber (match_operand 0 "register_operand"))]
"HARD_REGISTER_P (operands[0])
@@ -3434,49 +3455,3 @@ FALLTHRU:;
operands[1] = GEN_INT (imm0);
operands[2] = GEN_INT (imm1);
})
-
-(define_peephole2
- [(set (match_operand 0 "register_operand")
- (match_operand 1 "register_operand"))]
- "REG_NREGS (operands[0]) == 1 && GP_REG_P (REGNO (operands[0]))
- && REG_NREGS (operands[1]) == 1 && GP_REG_P (REGNO (operands[1]))
- && peep2_reg_dead_p (1, operands[1])"
- [(const_int 0)]
-{
- basic_block bb = BLOCK_FOR_INSN (curr_insn);
- rtx_insn *head = BB_HEAD (bb), *insn;
- rtx dest = operands[0], src = operands[1], pattern, t_dest, dest_orig;
- for (insn = PREV_INSN (curr_insn);
- insn && insn != head;
- insn = PREV_INSN (insn))
- if (CALL_P (insn))
- break;
- else if (INSN_P (insn))
- {
- if (GET_CODE (pattern = PATTERN (insn)) == SET
- && REG_P (t_dest = SET_DEST (pattern))
- && REG_NREGS (t_dest) == 1
- && REGNO (t_dest) == REGNO (src))
- {
- dest_orig = SET_DEST (pattern);
- SET_DEST (pattern) = gen_rtx_REG (GET_MODE (t_dest),
- REGNO (dest));
- extract_insn (insn);
- if (!constrain_operands (true, get_enabled_alternatives (insn)))
- {
- SET_DEST (pattern) = dest_orig;
- goto ABORT;
- }
- df_insn_rescan (insn);
- goto FALLTHRU;
- }
- if (reg_overlap_mentioned_p (dest, pattern)
- || reg_overlap_mentioned_p (src, pattern)
- || set_of (dest, insn)
- || set_of (src, insn))
- break;
- }
-ABORT:
- FAIL;
-FALLTHRU:;
-})