+(define_predicate "no_pic_small_symbol"
+ (match_code "symbol_ref")
+{
+ return !flag_pic & SYMBOL_REF_SMALL_P (op);
+})
s/&/&&/
Index: gcc/config/lm32/sfp-machine.h
Index: gcc/config/lm32/crti.S
Index: gcc/config/lm32/lib1funcs.S
Index: gcc/config/lm32/crtn.S
Index: gcc/config/lm32/arithmetic.c
Index: gcc/config/lm32/t-fprules-softfp
Index: gcc/config/lm32/t-lm32
Can you move these to libgcc?
+#define CPP_SPEC "\
+%{mmultiply-enabled:-D__multiply_enabled__} \
+%{mdivide-enabled:-D__divide_enabled__} \
+%{mbarrel-shift-enabled:-D__barrel_shift_enabled__} \
+%{msign-extend-enabled:-D__sign_extend_enabled__} \
+%{muser-enabled:-D__user_enabled__} \
It would be nicer to merge this into TARGET_CPU_CPP_BUILTINS.
You forgot to include constraints.md in your patch.
+(define_insn "*movqi_insn"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r")
+ (match_operand:QI 1 "general_operand" "m,r,r,K,L"))]
+ ""
+ "@
+ lbu %0, %1
+ or %0, %1, r0
+ sb %0, %1
+ addi %0, r0, %1
+ ori %0, r0, %1"
+ [(set_attr "type" "load,arith,store,arith,arith")]
You don't need both addi and ori alternatives, since all legal QImode
constants can be handled by addi. You can use the 'n' constraint here.
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
+ emit_insn (gen_movsi (operands[0], operands[1]));
+ DONE;
+ }
These bits aren't needed in the QI and HImode expanders.
Generally ports have an extra constraint to prevent MEM-to-MEM moves
from being generated by combine. You prevent them from happening in
initial rtl generation in your expanders, but you should probably have
something like
bool l32m_move_ok (enum machine_mode mode, rtx operands[2])
{
if (memory_operand (mode, operands[0]))
return register_or_zero_operand (mode, operands[1]);
return true;
}
Oh, that reminds me. I don't see a move alternative that allows R0
as the RHS of a store.
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "reloc_operand" ""))]
+ "!flag_pic"
+ [(set (match_dup 0) (high:SI (match_dup 1)))
+ (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
+ ""
+)
Why do you need this? Are you finding some pass putting these
symbols back together again? If so, you've missed making these
symbols not be legitimate constants. Yep:
+#define LEGITIMATE_CONSTANT_P(X) 1
that's exactly your problem.
+(define_insn "*movsi_lo_sum"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "reloc_operand" "i")))]
+ "!flag_pic"
+ "ori %0, %0, lo(%2)"
+ [(set_attr "type" "arith")]
Is this really an unsigned relocation? I strongly suggest that
you make the hi/lo relocation pair use a signed low-part. This
allows you to merge the lo_sum into a memory:
// foo++;
orhi r1, r0, hi(foo)
ori r1, r1, lo(foo)
lw r2, (r1+0)
addi r2, r2, 1
sw r2, (r1+0)
=>
orhi r1, r0, hi(foo)
lw r2, (r1+lo(foo))
addi r2, r2, 1
sw r2, (r1+lo(foo))
// x = foo[n]
orhi r1, r0, hi(foo)
ori r1, r1, lo(foo)
add r1, r1, r2
lw r3, (r1+0)
=>
orhi r1, r0, hi(foo)
add r1, r1, r2
lw r3, (r1+lo(foo))
FWIW, powerpc provides both signed and unsigned variants of
its hi relocation; "@ha" is supposed to mean "high for add"
or somesuch.
All that said, fixing this is not a requirement.
+(define_expand "indirect_jump"
+ [(set (pc) (match_operand 0 "register_operand" ""))]
+ ""
+ "
+{
+ emit_jump_insn (gen_indirect_jumpsi (operands[0]));
+ DONE;
+}")
+
+(define_insn "indirect_jumpsi"
+ [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
+ ""
+ "b %0"
+ [(set_attr "type" "uibranch")]
+)
You can eliminate the expander and just use the insn.
+(define_expand "call"
+ [(parallel [(call (match_operand 0 "memory_operand" "m")
+ (match_operand 1 "" ""))
+ (clobber (reg:SI RA_REGNUM))
+ ])]
+ ""
+ "
+{
+ rtx addr = XEXP (operands[0], 0);
+ if (!CONSTANT_ADDRESS_P (addr))
+ {
+ emit_call_insn (gen_call_via_regsi (addr, operands[1]));
+ DONE;
+ }
+}")
(define_expand "call"
[(parallel [(call (match_operand 0 "" "")
(match_operand 1 "" ""))
(clobber (reg:SI RA_REGNUM))])]
""
{
rtx addr = XEXP (operands[0], 0);
if (!CONSTANT_ADDRESS_P (addr))
XEXP (operands[0], 0) = force_reg (Pmode, addr);
})
(define_insn "*call"
[(call (mem (match_operand:SI 0 "call_operand" "r,s"))
(match_operand 1 "" ""))
(clobber (reg:SI RA_REGNUM))]
""
"@
call %0
calli %0"
[(set_attr "type" "call")])
(1) Don't use "memory_operand" for the call. The things you
are being passed aren't validized memories, the predicate
is never invoked, and it's a teeny bit confusing.
(2) No reason not to merge the register and symbolic insns.
(3) Similar for call_value, of course.
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
+ (match_operand:SI 2 "register_or_K_operand" "r,K")))]
You ought to use "%" for all of the commutative patterns for
which the two operands don't have identical constraints. I.e.
yes here on the add, but not on the beq pattern since those two
operands are both register_or_zero_operand.
Lots of nit picks, but your port is actually looking very good.
r~