This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH V3 05/11] bpf: new GCC port
Hi Richard.
> +(define_insn "mulsidi3"
> + [(set (match_operand:DI 0 "register_operand" "=r,r")
> + (sign_extend:DI
> + (mult:SI (match_operand:SI 1 "register_operand" "0,0")
> + (match_operand:SI 2 "reg_or_imm_operand" "r,I"))))]
> + ""
> + "mul32\t%0,%2"
> + [(set_attr "type" "alu32")])
Sorry, Segher was right and I was wrong: mulsidi3 is instead:
[(set (match_operand:DI 0 "register_operand" "=r,r")
(mult:DI
(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0"))
(sign_extend:DI (match_operand:SI 2 "reg_or_imm_operand" "r,I"))))]
i.e. extend the operands rather than the result. So the define_insn
shouldn't be called mulsidi3 after all.
Are you sure this is a sign extension though? From a quick look at the
kernel sources, I got the impression it was a zero extension instead.
You are right. This is from linux/kernel/bpf/core.c:
#define ALU(OPCODE, OP) \
ALU64_##OPCODE##_X: \
DST = DST OP SRC; \
CONT; \
ALU_##OPCODE##_X: \
DST = (u32) DST OP (u32) SRC; \
CONT; \
ALU64_##OPCODE##_K: \
DST = DST OP IMM; \
CONT; \
ALU_##OPCODE##_K: \
DST = (u32) DST OP (u32) IMM; \
CONT;
[...]
ALU(MUL, *)
So, mul32 zero-extends arguments and then multiplies, leaving the result
in the 64-bit register. This is an unsigned widening multiplication,
that according to the internal manuals should be handled with a pattern
like:
(define_insn "umulsidi3"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(mult:DI
(zero_extend:DI (match_operand:SI 1 "register_operand" "0,0"))
(zero_extend:DI (match_operand:SI 2 "reg_or_imm_operand" "r,I"))))]
""
"mul32\t%0,%2"
[(set_attr "type" "alu32")])