问题
I'm trying to write a C program mult.c that has a main function that receives 1 int argument (parsed with atoi(argv[1])
), that is some constant k
we want to multiply by.
This program will generate an assembly file mult.s
that implements
int mult(int x) {
return x * k;
}
for that constant k
. (This is a followup to Efficient Assembly multiplication)
For example: if main() in mult.c gets 14 as argument it may generate (though it is not minimal as later emphasized):
.section .text
.globl mult
mult: # by 14
movl %edi,%eax # arg passed in EDI
shl $3,%eax
movl %edi,%ecx
shl $2,%ecx
addl %ecx,%eax
movl %edi,%ecx
shl $1,%ecx
addl %ecx,%eax
ret
The assembly function recieves its argument in the %rdi register and returns its result in the %rax register.
I need to consider these following rules:
0) The assembly program should be minimal in terms of lines of code. (Dynamic instruction count). I'll worry about critical path latency later.
- if k is 0,1,-1 no need to multiply (obviously) -
xor %eax,%eax
,mov %edi, %eax
, orneg
- if k is 3,5,9 I then need to replace the multiplication command in LEA.
- if k is 3*2^n, 5*2^n, 9*2^n then I need to replace the multiplication command in LEA and shifting.
- all other cases suppose to work also of course.
I'm having trouble with cases 3 and 4.
- how can I identify a number is of this structure in my c program?
- what do I do with negative numbers?
And a general cases that relates to both, Am I just suppose to mask, add and shift my constant 32 times (the number of bits in an integer)? Is there anything better?
来源:https://stackoverflow.com/questions/59286585/finding-an-efficient-shift-add-lea-instruction-sequence-to-multiply-by-a-given-c