This commit is contained in:
pommicket 2022-02-11 14:34:54 -05:00
parent b13e16b517
commit 81d6850539
3 changed files with 151 additions and 2 deletions

View file

@ -90,7 +90,16 @@ function emit_mov_rax_imm64
:rax_imm64_0 :rax_imm64_0
emit_zero_rax() emit_zero_rax()
return return
function emit_mov_rbx_imm64
; 48 bb IMM64
argument imm64
*2code_output = 0xbb48
code_output += 2
*8code_output = imm64
code_output += 8
return
function emit_zero_rax function emit_zero_rax
; 31 c0 ; 31 c0
*2code_output = 0xc031 *2code_output = 0xc031
@ -265,6 +274,12 @@ function emit_movq_xmm1_rax
code_output += 1 code_output += 1
return return
function emit_movq_xmm1_xmm0
; f3 0f 7e c8
*4code_output = 0xc87e0ff3
code_output += 4
return
function emit_cvtss2sd_xmm0_xmm0 function emit_cvtss2sd_xmm0_xmm0
; f3 0f 5a c0 ; f3 0f 5a c0
*4code_output = 0xc05a0ff3 *4code_output = 0xc05a0ff3
@ -293,6 +308,15 @@ function emit_cvtsi2sd_xmm0_rax
code_output += 1 code_output += 1
return return
function emit_addsd_xmm0_xmm1
*4code_output = 0xc1580ff2
code_output += 4
return
function emit_subsd_xmm0_xmm1
*4code_output = 0xc15c0ff2
code_output += 4
return
function emit_neg_rax function emit_neg_rax
; 48 f7 d8 ; 48 f7 d8
@ -310,6 +334,60 @@ function emit_not_rax
code_output += 1 code_output += 1
return return
function emit_add_rax_rbx
; 48 01 d8
*2code_output = 0x0148
code_output += 2
*1code_output = 0xd8
code_output += 1
return
function emit_sub_rax_rbx
; 48 29 d8
*2code_output = 0x2948
code_output += 2
*1code_output = 0xd8
code_output += 1
return
function emit_imul_rbx
; 48 f7 eb
*2code_output = 0xf748
code_output += 2
*1code_output = 0xeb
code_output += 1
return
function emit_idiv_rbx
; 48 f7 fb
*2code_output = 0xf748
code_output += 2
*1code_output = 0xfb
code_output += 1
return
function emit_mul_rbx
; 48 f7 e3
*2code_output = 0xf748
code_output += 2
*1code_output = 0xe3
code_output += 1
return
function emit_div_rbx
; 48 f7 f3
*2code_output = 0xf748
code_output += 2
*1code_output = 0xf3
code_output += 1
return
function emit_cqo
; 48 99
*2code_output = 0x9948
code_output += 2
return
function emit_xor_rax_rbx function emit_xor_rax_rbx
; 48 31 d8 ; 48 31 d8
*2code_output = 0x3148 *2code_output = 0x3148
@ -655,13 +733,31 @@ function generate_push_expression_casted
expr = generate_push_expression(statement, expr) expr = generate_push_expression(statement, expr)
generate_cast_top_of_stack(statement, from_type, to_type) generate_cast_top_of_stack(statement, from_type, to_type)
return expr return expr
; if type is a pointer type, returns the size of the underlying type
; otherwise, returns 1
; this is so that (int *)p + 5 adds 20 to p, instead of 5
function scale_rax_for_addition_with
argument type
local p
p = types + type
if *1p != TYPE_POINTER goto return_0
local n
p = type + 1
n = type_sizeof(p)
; now scale rax by n
emit_mov_rbx_imm64(n)
emit_mul_rbx()
return
; `statement` is used for errors ; `statement` is used for errors
; returns pointer to end of expression ; returns pointer to end of expression
function generate_push_expression function generate_push_expression
argument statement argument statement
argument expr argument expr
local c local c
local d
local p local p
local type local type
type = expr + 4 type = expr + 4
@ -675,6 +771,7 @@ function generate_push_expression
if c == EXPRESSION_UNARY_MINUS goto generate_unary_minus if c == EXPRESSION_UNARY_MINUS goto generate_unary_minus
if c == EXPRESSION_BITWISE_NOT goto generate_unary_bitwise_not if c == EXPRESSION_BITWISE_NOT goto generate_unary_bitwise_not
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
die(.str_genpushexprNI) die(.str_genpushexprNI)
:str_genpushexprNI :str_genpushexprNI
@ -716,6 +813,54 @@ function generate_push_expression
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, type) generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type)
return expr return expr
:generate_add
expr += 8
c = expr + 4 ; type of 1st operand
expr = generate_push_expression_casted(statement, expr, type)
d = expr + 4 ; type of 2nd operand
expr = generate_push_expression_casted(statement, expr, type)
p = types + type
if *1p == TYPE_FLOAT goto generate_add_floats
if *1p == TYPE_DOUBLE goto generate_add_doubles
c = *4c
d = *4d
emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (first operand)
scale_rax_for_addition_with(d) ; in case this is a pointer addition
emit_mov_reg(REG_RSI, REG_RAX) ; store away 2nd operand in rsi
emit_mov_rax_qword_rsp_plus_imm32(0) ; mov rax, [rsp] (second operand)
scale_rax_for_addition_with(c) ; in case this is a pointer addition
emit_mov_reg(REG_RBX, REG_RSI) ; put 1st operand in rbx
emit_add_rax_rbx()
emit_add_rsp_imm32(8) ; add rsp, 8
emit_mov_qword_rsp_rax() ; mov [rsp], rax
return expr
:generate_add_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_addsd_xmm0_xmm1() ; addsd 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 expr
:generate_add_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_addsd_xmm0_xmm1() ; addsd 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 expr
:generate_unary_logical_not :generate_unary_logical_not
expr += 8 expr += 8
p = expr + 4 p = expr + 4

View file

@ -1,3 +1,3 @@
long main(int argc, char **argv) { long main(int argc, char **argv) {
return !1e-100; return -(3.5+2.5);
} }

View file

@ -112,6 +112,7 @@ ax bx cx dx sp bp si di
│ Instruction │ Encoding │ Description │ │ Instruction │ Encoding │ Description │
├──────────────────────┼───────────────────┼────────────────────────────────────────┤ ├──────────────────────┼───────────────────┼────────────────────────────────────────┤
│ mov rax, IMM64 │ 48 b8 IMM64 │ set rax to the 64-bit value IMM64 │ │ mov rax, IMM64 │ 48 b8 IMM64 │ set rax to the 64-bit value IMM64 │
│ mov rbx, IMM64 │ 48 bb IMM64 │ set rbx to the 64-bit value IMM64 │
│ xor eax, eax │ 31 c0 │ set rax to 0 (shorter than mov rax, 0) │ │ xor eax, eax │ 31 c0 │ set rax to 0 (shorter than mov rax, 0) │
│ xor edx, edx │ 31 d2 │ set rdx to 0 │ │ xor edx, edx │ 31 d2 │ set rdx to 0 │
│ mov RDEST, RSRC │ 48 89 (DEST|SRC<<3|0xc0) set register DEST to current │ mov RDEST, RSRC │ 48 89 (DEST|SRC<<3|0xc0) set register DEST to current
@ -184,11 +185,14 @@ ax bx cx dx sp bp si di
| movq rax, xmm0 | 66 48 0f 7e c0 | set rax to xmm0 | | movq rax, xmm0 | 66 48 0f 7e c0 | set rax to xmm0 |
| movq xmm0, rax | 66 48 0f 6e c0 | set xmm0 to rax | | movq xmm0, rax | 66 48 0f 6e c0 | set xmm0 to rax |
| movq xmm1, rax | 66 48 0f 6e c8 | set xmm1 to rax | | movq xmm1, rax | 66 48 0f 6e c8 | set xmm1 to rax |
| movq xmm1, xmm0 | f3 0f 7e c8 | set xmm1 to xmm0 |
| cvtss2sd xmm0, xmm0 | f3 0f 5a c0 | convert xmm0 from float to double | | cvtss2sd xmm0, xmm0 | f3 0f 5a c0 | convert xmm0 from float to double |
| cvtsd2ss xmm0, xmm0 | f2 0f 5a c0 | convert xmm0 from double to float | | cvtsd2ss xmm0, xmm0 | f2 0f 5a c0 | convert xmm0 from double to float |
| cvttsd2si rax, xmm0 | f2 48 0f 2c c0 | convert double in xmm0 to int in rax | | cvttsd2si rax, xmm0 | f2 48 0f 2c c0 | convert double in xmm0 to int in rax |
| cvtsi2sd xmm0, rax | f2 48 0f 2a c0 | convert int in rax to double in xmm0 | | cvtsi2sd xmm0, rax | f2 48 0f 2a c0 | convert int in rax to double in xmm0 |
| 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 |
| subsd xmm0, xmm1 | f2 0f 5c c1 | subtract xmm1 from xmm0 |
│ 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 │