===================================================================
@@ -304,3 +304,15 @@
"1"
"rl78_expand_compare (operands);"
)
+
+(define_expand "xorhi3"
+ [(set (match_operand:HI 0 "register_operand")
+ (xor:HI (match_operand:HI 1 "register_operand")
+ (match_operand:HI 2 "nonmemory_operand")))
+ ]
+ ""
+ "if (GET_CODE (operands[2]) == SYMBOL_REF)
+ operands[2] = force_reg (HImode, operands[2]);
+ if (rl78_force_nonfar_3 (operands, gen_xorhi3))
+ DONE;"
+)
===================================================================
@@ -549,3 +576,34 @@
[(set (reg:QI A_REG) (and:QI (reg:QI A_REG) (match_dup 1)))]
)
+(define_insn "*andhi3_real"
+ [(set (match_operand:HI 0 "register_operand" "=Av")
+ (and:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:HI 2 "immediate_operand" "n")))
+ ]
+ "rl78_real_insns_ok ()"
+ "and\t%q0, %q2 \; and\t%Q0, %Q2"
+)
+
+(define_insn "*nandhi3_real"
+ [(set (match_operand:HI 0 "register_operand" "=A")
+ (and:HI (neg:HI (match_operand:HI 1 "register_operand" "0"))
+ (match_operand:HI 2 "immediate_operand" "n")))
+ ]
+ "rl78_real_insns_ok ()"
+ "xor a, #0xff @ xch a, x @ xor a, #0xff @ xch a, x @ addw ax, #1 @ and a, %Q2 @ xch a, x @ and a, %q2 @ xch a, x"
+)
+
+;; Necessary because GCC insists upon being able to perform binary
+;; operations upon pointers. Failure to provide these patterns
+;; results in GCC generating illegal subregs, eg: (SUBREG:QI (REG:HI 33) 1)
+
+(define_insn "*xorhi3_real"
+ [(set (match_operand:HI 0 "register_operand" "=A")
+ (xor:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:HI 2 "nonmemory_operand" "ABDTn")))
+ ]
+ "rl78_real_insns_ok ()"
+ "xor a, %Q2 \; xch a, x \; xor a, %q2 \; xch a, x"
+)
+
===================================================================
@@ -405,3 +405,34 @@
]
"rl78_setup_peep_movhi (operands);"
)
+
+(define_insn "*andhi3_virt"
+ [(set (match_operand:HI 0 "register_operand" "=v")
+ (and:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:HI 2 "immediate_operand" "n")))
+ ]
+ "rl78_virt_insns_ok ()"
+ "v.and\t%0, %1, %2"
+)
+
+(define_insn "*nandhi3_virt"
+ [(set (match_operand:HI 0 "register_operand" "=v")
+ (and:HI (neg:HI (match_operand:HI 1 "register_operand" "0"))
+ (match_operand:HI 2 "immediate_operand" "n")))
+ ]
+ "rl78_virt_insns_ok ()"
+ "v.nand\t%0, %1, %2"
+)
+
+;; Necessary because GCC insists upon being able to perform binary
+;; operations upon pointers. Failure to provide these patterns
+;; results in GCC generating illegal subregs, eg: (SUBREG:QI (REG:HI 33) 1)
+
+(define_insn "*xorhi3_virt"
+ [(set (match_operand:HI 0 "register_operand" "=v")
+ (xor:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:HI 2 "nonmemory_operand" "vn")))
+ ]
+ "rl78_virt_insns_ok () && GET_CODE (operands[2]) != SYMBOL_REF"
+ "v.xor.hi\t%0, %1, %2"
+)