multiplication and division
This commit is contained in:
parent
8b68a433ff
commit
d44625524a
3 changed files with 130 additions and 15 deletions
127
05/codegen.b
127
05/codegen.b
|
@ -417,6 +417,16 @@ function emit_subsd_xmm0_xmm1
|
||||||
code_output += 4
|
code_output += 4
|
||||||
return
|
return
|
||||||
|
|
||||||
|
function emit_mulsd_xmm0_xmm1
|
||||||
|
*4code_output = 0xc1590ff2
|
||||||
|
code_output += 4
|
||||||
|
return
|
||||||
|
|
||||||
|
function emit_divsd_xmm0_xmm1
|
||||||
|
*4code_output = 0xc15e0ff2
|
||||||
|
code_output += 4
|
||||||
|
return
|
||||||
|
|
||||||
function emit_neg_rax
|
function emit_neg_rax
|
||||||
; 48 f7 d8
|
; 48 f7 d8
|
||||||
*2code_output = 0xf748
|
*2code_output = 0xf748
|
||||||
|
@ -881,6 +891,7 @@ function generate_stack_add
|
||||||
emit_add_rax_rbx() ; add rax, rbx
|
emit_add_rax_rbx() ; add rax, rbx
|
||||||
emit_add_rsp_imm32(8) ; add rsp, 8
|
emit_add_rsp_imm32(8) ; add rsp, 8
|
||||||
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
|
generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, out_type)
|
||||||
return
|
return
|
||||||
|
|
||||||
:generate_add_floats
|
:generate_add_floats
|
||||||
|
@ -890,6 +901,7 @@ function generate_stack_add
|
||||||
emit_movq_xmm1_xmm0() ; movq xmm1, xmm0
|
emit_movq_xmm1_xmm0() ; movq xmm1, xmm0
|
||||||
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
||||||
emit_movq_xmm0_rax() ; movq xmm0, rax
|
emit_movq_xmm0_rax() ; movq xmm0, rax
|
||||||
|
emit_cvtss2sd_xmm0_xmm0() ; cvtss2sd xmm0, xmm0
|
||||||
emit_addsd_xmm0_xmm1() ; addsd xmm0, xmm1
|
emit_addsd_xmm0_xmm1() ; addsd xmm0, xmm1
|
||||||
emit_cvtsd2ss_xmm0_xmm0() ; cvtsd2ss xmm0, xmm0
|
emit_cvtsd2ss_xmm0_xmm0() ; cvtsd2ss xmm0, xmm0
|
||||||
emit_movq_rax_xmm0() ; movq rax, xmm0
|
emit_movq_rax_xmm0() ; movq rax, xmm0
|
||||||
|
@ -931,6 +943,7 @@ function generate_stack_sub
|
||||||
emit_sub_rax_rbx() ; sub rax, rbx
|
emit_sub_rax_rbx() ; sub rax, rbx
|
||||||
emit_add_rsp_imm32(8) ; add rsp, 8
|
emit_add_rsp_imm32(8) ; add rsp, 8
|
||||||
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
|
generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, out_type)
|
||||||
return
|
return
|
||||||
|
|
||||||
:generate_sub_pointers
|
:generate_sub_pointers
|
||||||
|
@ -969,6 +982,7 @@ function generate_stack_sub
|
||||||
emit_movq_xmm1_xmm0() ; movq xmm1, xmm0
|
emit_movq_xmm1_xmm0() ; movq xmm1, xmm0
|
||||||
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
||||||
emit_movq_xmm0_rax() ; movq xmm0, rax
|
emit_movq_xmm0_rax() ; movq xmm0, rax
|
||||||
|
emit_cvtss2sd_xmm0_xmm0() ; cvtss2sd xmm0, xmm0
|
||||||
emit_subsd_xmm0_xmm1() ; subsd xmm0, xmm1
|
emit_subsd_xmm0_xmm1() ; subsd xmm0, xmm1
|
||||||
emit_cvtsd2ss_xmm0_xmm0() ; cvtsd2ss xmm0, xmm0
|
emit_cvtsd2ss_xmm0_xmm0() ; cvtsd2ss xmm0, xmm0
|
||||||
emit_movq_rax_xmm0() ; movq rax, xmm0
|
emit_movq_rax_xmm0() ; movq rax, xmm0
|
||||||
|
@ -987,6 +1001,105 @@ function generate_stack_sub
|
||||||
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
return
|
return
|
||||||
|
|
||||||
|
; pop the top two things off of the stack, and push their product
|
||||||
|
function generate_stack_mul
|
||||||
|
argument statement ; for errors
|
||||||
|
argument type
|
||||||
|
local p
|
||||||
|
p = types + type
|
||||||
|
if *1p == TYPE_FLOAT goto generate_mul_floats
|
||||||
|
if *1p == TYPE_DOUBLE goto generate_mul_doubles
|
||||||
|
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(0) ; mov rax, [rsp] (second operand)
|
||||||
|
emit_mov_reg(REG_RBX, REG_RAX) ; mov rbx, rax
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
||||||
|
emit_mul_rbx() ; mul rbx
|
||||||
|
emit_add_rsp_imm32(8) ; add rsp, 8
|
||||||
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
|
generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type)
|
||||||
|
return
|
||||||
|
|
||||||
|
:generate_mul_floats
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(0) ; mov rax, [rsp] (second operand)
|
||||||
|
emit_movq_xmm0_rax() ; movq xmm0, rax
|
||||||
|
emit_cvtss2sd_xmm0_xmm0() ; cvtss2sd xmm0, xmm0
|
||||||
|
emit_movq_xmm1_xmm0() ; movq xmm1, xmm0
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
||||||
|
emit_movq_xmm0_rax() ; movq xmm0, rax
|
||||||
|
emit_cvtss2sd_xmm0_xmm0() ; cvtss2sd xmm0, xmm0
|
||||||
|
emit_mulsd_xmm0_xmm1() ; mulsd xmm0, xmm1
|
||||||
|
emit_cvtsd2ss_xmm0_xmm0() ; cvtsd2ss xmm0, xmm0
|
||||||
|
emit_movq_rax_xmm0() ; movq rax, xmm0
|
||||||
|
emit_add_rsp_imm32(8) ; add rsp, 8
|
||||||
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
|
return
|
||||||
|
|
||||||
|
:generate_mul_doubles
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(0) ; mov rax, [rsp] (second operand)
|
||||||
|
emit_movq_xmm1_rax() ; movq xmm1, rax
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
||||||
|
emit_movq_xmm0_rax() ; movq xmm0, rax
|
||||||
|
emit_mulsd_xmm0_xmm1() ; mulsd xmm0, xmm1
|
||||||
|
emit_movq_rax_xmm0() ; movq rax, xmm0
|
||||||
|
emit_add_rsp_imm32(8) ; add rsp, 8
|
||||||
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
|
return
|
||||||
|
|
||||||
|
; pop the top two things off of the stack, and push their quotient
|
||||||
|
function generate_stack_div
|
||||||
|
argument statement ; for errors
|
||||||
|
argument type
|
||||||
|
local p
|
||||||
|
local c
|
||||||
|
p = types + type
|
||||||
|
if *1p == TYPE_FLOAT goto generate_div_floats
|
||||||
|
if *1p == TYPE_DOUBLE goto generate_div_doubles
|
||||||
|
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(0) ; mov rax, [rsp] (second operand)
|
||||||
|
emit_mov_reg(REG_RBX, REG_RAX) ; mov rbx, rax
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
||||||
|
c = *1p & 1
|
||||||
|
if c == 1 goto generate_div_signed
|
||||||
|
:generate_div_unsigned
|
||||||
|
emit_zero_rdx() ; xor edx, edx
|
||||||
|
emit_div_rbx() ; div rbx
|
||||||
|
goto generate_div_cont
|
||||||
|
:generate_div_signed
|
||||||
|
emit_cqo() ; cqo
|
||||||
|
emit_idiv_rbx() ; idiv rbx
|
||||||
|
goto generate_div_cont
|
||||||
|
:generate_div_cont
|
||||||
|
emit_add_rsp_imm32(8) ; add rsp, 8
|
||||||
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
|
generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type)
|
||||||
|
return
|
||||||
|
|
||||||
|
:generate_div_floats
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(0) ; mov rax, [rsp] (second operand)
|
||||||
|
emit_movq_xmm0_rax() ; movq xmm0, rax
|
||||||
|
emit_cvtss2sd_xmm0_xmm0() ; cvtss2sd xmm0, xmm0
|
||||||
|
emit_movq_xmm1_xmm0() ; movq xmm1, xmm0
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
||||||
|
emit_movq_xmm0_rax() ; movq xmm0, rax
|
||||||
|
emit_cvtss2sd_xmm0_xmm0() ; cvtss2sd xmm0, xmm0
|
||||||
|
emit_divsd_xmm0_xmm1() ; divsd xmm0, xmm1
|
||||||
|
emit_cvtsd2ss_xmm0_xmm0() ; cvtsd2ss xmm0, xmm0
|
||||||
|
emit_movq_rax_xmm0() ; movq rax, xmm0
|
||||||
|
emit_add_rsp_imm32(8) ; add rsp, 8
|
||||||
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
|
return
|
||||||
|
|
||||||
|
:generate_div_doubles
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(0) ; mov rax, [rsp] (second operand)
|
||||||
|
emit_movq_xmm1_rax() ; movq xmm1, rax
|
||||||
|
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
|
||||||
|
emit_movq_xmm0_rax() ; movq xmm0, rax
|
||||||
|
emit_divsd_xmm0_xmm1() ; divsd xmm0, xmm1
|
||||||
|
emit_movq_rax_xmm0() ; movq rax, xmm0
|
||||||
|
emit_add_rsp_imm32(8) ; add rsp, 8
|
||||||
|
emit_mov_qword_rsp_rax() ; mov [rsp], rax
|
||||||
|
return
|
||||||
|
|
||||||
; pop a pointer off of the stack, then push the dereferenced value according to `type`
|
; pop a pointer off of the stack, then push the dereferenced value according to `type`
|
||||||
function generate_stack_dereference
|
function generate_stack_dereference
|
||||||
argument statement ; for errors
|
argument statement ; for errors
|
||||||
|
@ -1178,6 +1291,8 @@ function generate_push_expression
|
||||||
if c == EXPRESSION_LOGICAL_NOT goto generate_unary_logical_not
|
if c == EXPRESSION_LOGICAL_NOT goto generate_unary_logical_not
|
||||||
if c == EXPRESSION_ADD goto generate_add
|
if c == EXPRESSION_ADD goto generate_add
|
||||||
if c == EXPRESSION_SUB goto generate_sub
|
if c == EXPRESSION_SUB goto generate_sub
|
||||||
|
if c == EXPRESSION_MUL goto generate_mul
|
||||||
|
if c == EXPRESSION_DIV goto generate_div
|
||||||
if c == EXPRESSION_GLOBAL_VARIABLE goto generate_global_variable
|
if c == EXPRESSION_GLOBAL_VARIABLE goto generate_global_variable
|
||||||
if c == EXPRESSION_LOCAL_VARIABLE goto generate_local_variable
|
if c == EXPRESSION_LOCAL_VARIABLE goto generate_local_variable
|
||||||
if c == EXPRESSION_DEREFERENCE goto generate_dereference
|
if c == EXPRESSION_DEREFERENCE goto generate_dereference
|
||||||
|
@ -1276,6 +1391,18 @@ function generate_push_expression
|
||||||
expr = generate_push_expression_casted(statement, expr, type)
|
expr = generate_push_expression_casted(statement, expr, type)
|
||||||
generate_stack_sub(statement, *4c, *4d, type)
|
generate_stack_sub(statement, *4c, *4d, type)
|
||||||
return expr
|
return expr
|
||||||
|
:generate_mul
|
||||||
|
expr += 8
|
||||||
|
expr = generate_push_expression_casted(statement, expr, type)
|
||||||
|
expr = generate_push_expression_casted(statement, expr, type)
|
||||||
|
generate_stack_mul(statement, type)
|
||||||
|
return expr
|
||||||
|
:generate_div
|
||||||
|
expr += 8
|
||||||
|
expr = generate_push_expression_casted(statement, expr, type)
|
||||||
|
expr = generate_push_expression_casted(statement, expr, type)
|
||||||
|
generate_stack_div(statement, type)
|
||||||
|
return expr
|
||||||
:generate_unary_logical_not
|
:generate_unary_logical_not
|
||||||
expr += 8
|
expr += 8
|
||||||
p = expr + 4
|
p = expr + 4
|
||||||
|
|
16
05/main.c
16
05/main.c
|
@ -1,18 +1,4 @@
|
||||||
static char x = -2;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int x;
|
|
||||||
char y;
|
|
||||||
long z;
|
|
||||||
long q;
|
|
||||||
} Structure;
|
|
||||||
|
|
||||||
Structure a = {1,2,3,-4};
|
|
||||||
|
|
||||||
long main(int argc, char **argv) {
|
long main(int argc, char **argv) {
|
||||||
Structure a = {1,2,3,4};
|
return ((float)1 / (float)3) * (float)3;
|
||||||
int x = 100;
|
|
||||||
a;a;a;a;a;
|
|
||||||
x = x + x, x = x + 2;
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,6 +194,8 @@ ax bx cx dx sp bp si di
|
||||||
| comisd xmm0, xmm1 | 66 0f 2f c1 | compare xmm0 and xmm1 |
|
| comisd xmm0, xmm1 | 66 0f 2f c1 | compare xmm0 and xmm1 |
|
||||||
| addsd xmm0, xmm1 | f2 0f 58 c1 | add xmm1 to xmm0 |
|
| addsd xmm0, xmm1 | f2 0f 58 c1 | add xmm1 to xmm0 |
|
||||||
| subsd xmm0, xmm1 | f2 0f 5c c1 | subtract xmm1 from xmm0 |
|
| subsd xmm0, xmm1 | f2 0f 5c c1 | subtract xmm1 from xmm0 |
|
||||||
|
| mulsd xmm0, xmm1 | f2 0f 59 c1 | multiply xmm0 by xmm1 |
|
||||||
|
| divsd xmm0, xmm1 | f2 0f 5e c1 | divide xmm0 by xmm1 |
|
||||||
│ call rax │ ff d0 │ call the function at address rax │
|
│ call rax │ ff d0 │ call the function at address rax │
|
||||||
│ ret │ c3 │ return from function │
|
│ ret │ c3 │ return from function │
|
||||||
│ syscall │ 0f 05 │ execute a system call │
|
│ syscall │ 0f 05 │ execute a system call │
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue