aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pru/pru.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/pru/pru.md')
-rw-r--r--gcc/config/pru/pru.md40
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md
index 2f1bc21..125444c 100644
--- a/gcc/config/pru/pru.md
+++ b/gcc/config/pru/pru.md
@@ -51,6 +51,10 @@
;; Enumeration of UNSPECs.
+(define_c_enum "unspec" [
+ UNSPEC_LMBD
+])
+
(define_c_enum "unspecv" [
UNSPECV_DELAY_CYCLES_START
UNSPECV_DELAY_CYCLES_END
@@ -61,6 +65,8 @@
UNSPECV_LOOP_BEGIN
UNSPECV_LOOP_END
+ UNSPECV_HALT
+
UNSPECV_BLOCKAGE
])
@@ -1020,3 +1026,37 @@
""
"nop\\t# Loop end guard"
[(set_attr "type" "alu")])
+
+;; HALT instruction.
+(define_insn "pru_halt"
+ [(unspec_volatile [(const_int 0)] UNSPECV_HALT)]
+ ""
+ "halt"
+ [(set_attr "type" "control")])
+
+;; Count Leading Zeros implemented using LMBD.
+;; LMBD returns 32 if bit value is not present, and we subtract 31 to get CLZ.
+;; Hence we get a defined value -1 for CLZ_DEFINED_VALUE_AT_ZERO.
+(define_expand "clz<mode>2"
+ [(set (match_operand:QISI 0 "register_operand")
+ (clz:QISI (match_operand:QISI 1 "register_operand")))]
+ ""
+{
+ rtx dst = operands[0];
+ rtx src = operands[1];
+ rtx tmpval = gen_reg_rtx (<MODE>mode);
+
+ emit_insn (gen_pru_lmbd (<MODE>mode, tmpval, src, const1_rtx));
+ emit_insn (gen_sub3_insn (dst, GEN_INT (31), tmpval));
+ DONE;
+})
+
+;; Left Most Bit Detect operation, which maps to a single instruction.
+(define_expand "@pru_lmbd<mode>"
+ [(set (match_operand:QISI 0 "register_operand")
+ (unspec:QISI
+ [(match_operand:QISI 1 "register_operand")
+ (match_operand:QISI 2 "reg_or_ubyte_operand")]
+ UNSPEC_LMBD))]
+ ""
+ "")