more consterxprs
This commit is contained in:
parent
a7ace346b7
commit
08c49a193f
6 changed files with 127 additions and 26 deletions
29
04/in03
29
04/in03
|
@ -1005,7 +1005,7 @@ align
|
||||||
I=:line
|
I=:line
|
||||||
call :set_rax_to_rvalue
|
call :set_rax_to_rvalue
|
||||||
call :set_rbx_to_rdi
|
call :set_rbx_to_rdi
|
||||||
call :emit_zero_rdx_idiv_rbx
|
call :emit_cqo_idiv_rbx
|
||||||
I=:line
|
I=:line
|
||||||
call :set_lvalue_to_rax
|
call :set_lvalue_to_rax
|
||||||
!:read_line
|
!:read_line
|
||||||
|
@ -1014,7 +1014,7 @@ align
|
||||||
I=:line
|
I=:line
|
||||||
call :set_rax_to_rvalue
|
call :set_rax_to_rvalue
|
||||||
call :set_rbx_to_rdi
|
call :set_rbx_to_rdi
|
||||||
call :emit_zero_rdx_idiv_rbx
|
call :emit_cqo_idiv_rbx
|
||||||
call :set_rax_to_rdx
|
call :set_rax_to_rdx
|
||||||
I=:line
|
I=:line
|
||||||
call :set_lvalue_to_rax
|
call :set_lvalue_to_rax
|
||||||
|
@ -1475,11 +1475,11 @@ align
|
||||||
|
|
||||||
:rvalue_div
|
:rvalue_div
|
||||||
call :set_rbx_to_rsi
|
call :set_rbx_to_rsi
|
||||||
!:emit_zero_rdx_idiv_rbx
|
!:emit_cqo_idiv_rbx
|
||||||
|
|
||||||
:rvalue_rem
|
:rvalue_rem
|
||||||
call :set_rbx_to_rsi
|
call :set_rbx_to_rsi
|
||||||
call :emit_zero_rdx_idiv_rbx
|
call :emit_cqo_idiv_rbx
|
||||||
call :set_rax_to_rdx
|
call :set_rax_to_rdx
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1745,16 +1745,6 @@ align
|
||||||
x31
|
x31
|
||||||
xc0
|
xc0
|
||||||
|
|
||||||
:zero_rdx
|
|
||||||
J=d4
|
|
||||||
I=:xor_edx_edx
|
|
||||||
D=d2
|
|
||||||
syscall x1
|
|
||||||
return
|
|
||||||
:xor_edx_edx
|
|
||||||
x31
|
|
||||||
xd2
|
|
||||||
|
|
||||||
:set_rbx_to_rax
|
:set_rbx_to_rax
|
||||||
J=d4
|
J=d4
|
||||||
I=:mov_rbx_rax
|
I=:mov_rbx_rax
|
||||||
|
@ -2014,14 +2004,15 @@ align
|
||||||
xf7
|
xf7
|
||||||
xeb
|
xeb
|
||||||
|
|
||||||
:emit_zero_rdx_idiv_rbx
|
:emit_cqo_idiv_rbx
|
||||||
call :zero_rdx
|
|
||||||
J=d4
|
J=d4
|
||||||
I=:idiv_rbx
|
I=:cqo_idiv_rbx
|
||||||
D=d3
|
D=d5
|
||||||
syscall x1
|
syscall x1
|
||||||
return
|
return
|
||||||
:idiv_rbx
|
:cqo_idiv_rbx
|
||||||
|
x48
|
||||||
|
x99
|
||||||
x48
|
x48
|
||||||
xf7
|
xf7
|
||||||
xfb
|
xfb
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
; uchar kind (one of the constants below)
|
; uchar kind (one of the constants below)
|
||||||
; uchar info
|
; uchar info
|
||||||
; ushort (padding)
|
; ushort (padding)
|
||||||
; uint type (0 if expression hasn't been typed yet)
|
; uint type
|
||||||
; immediately following the header in memory are the arguments of the expression
|
; immediately following the header in memory are the arguments of the expression
|
||||||
; - for constant ints, the 64-bit integral value
|
; - for constant ints, the 64-bit integral value
|
||||||
; - for constant floats, the 64-bit double value (even if expression has type float)
|
; - for constant floats, the 64-bit double value (even if expression has type float)
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
long double d;
|
long double d;
|
||||||
} (*x)(void);
|
} (*x)(void);
|
||||||
*/
|
*/
|
||||||
typedef long int unsigned Foo[3 * 3];
|
typedef long int unsigned Foo[19 + (-3) % 187 - 28 + 5 * 6];
|
||||||
|
|
44
05/parse.b
44
05/parse.b
|
@ -943,6 +943,7 @@ function evaluate_constant_expression
|
||||||
argument p_value
|
argument p_value
|
||||||
local a
|
local a
|
||||||
local b
|
local b
|
||||||
|
local p
|
||||||
|
|
||||||
if *1expr == EXPRESSION_CONSTANT_INT goto eval_constant_int
|
if *1expr == EXPRESSION_CONSTANT_INT goto eval_constant_int
|
||||||
if *1expr == EXPRESSION_IDENTIFIER goto eval_constant_identifier
|
if *1expr == EXPRESSION_IDENTIFIER goto eval_constant_identifier
|
||||||
|
@ -951,8 +952,11 @@ function evaluate_constant_expression
|
||||||
if *1expr == EXPRESSION_BITWISE_NOT goto eval_bitwise_not
|
if *1expr == EXPRESSION_BITWISE_NOT goto eval_bitwise_not
|
||||||
if *1expr == EXPRESSION_LOGICAL_NOT goto eval_logical_not
|
if *1expr == EXPRESSION_LOGICAL_NOT goto eval_logical_not
|
||||||
if *1expr == EXPRESSION_CAST goto eval_todo ; @TODO
|
if *1expr == EXPRESSION_CAST goto eval_todo ; @TODO
|
||||||
if *1expr == EXPRESSION_LOGICAL_NOT goto eval_logical_not
|
if *1expr == EXPRESSION_ADD goto eval_add
|
||||||
|
if *1expr == EXPRESSION_SUB goto eval_sub
|
||||||
if *1expr == EXPRESSION_MUL goto eval_mul
|
if *1expr == EXPRESSION_MUL goto eval_mul
|
||||||
|
if *1expr == EXPRESSION_DIV goto eval_div
|
||||||
|
if *1expr == EXPRESSION_REMAINDER goto eval_remainder
|
||||||
byte 0xcc
|
byte 0xcc
|
||||||
|
|
||||||
:eval_todo
|
:eval_todo
|
||||||
|
@ -998,13 +1002,49 @@ function evaluate_constant_expression
|
||||||
:eval_logical_not0
|
:eval_logical_not0
|
||||||
*8p_value = 1
|
*8p_value = 1
|
||||||
return expr
|
return expr
|
||||||
|
:eval_add
|
||||||
|
expr += 8
|
||||||
|
expr = evaluate_constant_expression(expr, &a)
|
||||||
|
expr = evaluate_constant_expression(expr, &b)
|
||||||
|
*8p_value = a + b
|
||||||
|
return expr
|
||||||
|
:eval_sub
|
||||||
|
expr += 8
|
||||||
|
expr = evaluate_constant_expression(expr, &a)
|
||||||
|
expr = evaluate_constant_expression(expr, &b)
|
||||||
|
*8p_value = a - b
|
||||||
|
return expr
|
||||||
:eval_mul
|
:eval_mul
|
||||||
expr += 8
|
expr += 8
|
||||||
expr = evaluate_constant_expression(expr, &a)
|
expr = evaluate_constant_expression(expr, &a)
|
||||||
expr = evaluate_constant_expression(expr, &b)
|
expr = evaluate_constant_expression(expr, &b)
|
||||||
*8p_value = a * b
|
*8p_value = a * b
|
||||||
return expr
|
return expr
|
||||||
|
:eval_div
|
||||||
|
p = expr + 4 ; pointer to type
|
||||||
|
expr += 8
|
||||||
|
expr = evaluate_constant_expression(expr, &a)
|
||||||
|
expr = evaluate_constant_expression(expr, &b)
|
||||||
|
if *1p == TYPE_UNSIGNED_LONG goto eval_div_unsigned
|
||||||
|
; division is signed or uses a small type, so we can use 64-bit signed division
|
||||||
|
*8p_value = a / b
|
||||||
|
return expr
|
||||||
|
:eval_div_unsigned
|
||||||
|
; must use unsigned division
|
||||||
|
divmod_unsigned(a, b, p_value, &a)
|
||||||
|
return expr
|
||||||
|
:eval_remainder
|
||||||
|
p = expr + 4 ; pointer to type
|
||||||
|
expr += 8
|
||||||
|
expr = evaluate_constant_expression(expr, &a)
|
||||||
|
expr = evaluate_constant_expression(expr, &b)
|
||||||
|
if *1p == TYPE_UNSIGNED_LONG goto eval_rem_unsigned
|
||||||
|
*8p_value = a % b
|
||||||
|
return expr
|
||||||
|
:eval_rem_unsigned
|
||||||
|
divmod_unsigned(a, b, &a, p_value)
|
||||||
|
return expr
|
||||||
|
|
||||||
; the "usual conversions" for binary operators, as the C standard calls it
|
; the "usual conversions" for binary operators, as the C standard calls it
|
||||||
function expr_binary_type_usual_conversions
|
function expr_binary_type_usual_conversions
|
||||||
argument token ; for errors
|
argument token ; for errors
|
||||||
|
|
75
05/util.b
75
05/util.b
|
@ -25,6 +25,75 @@ function full_multiply_signed
|
||||||
*8p_upper = upper
|
*8p_upper = upper
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
function divmod_unsigned
|
||||||
|
argument a
|
||||||
|
argument b
|
||||||
|
argument p_quotient
|
||||||
|
argument p_remainder
|
||||||
|
local q
|
||||||
|
local r
|
||||||
|
|
||||||
|
; mov rax, [rbp-16]
|
||||||
|
byte 0x48
|
||||||
|
byte 0x8b
|
||||||
|
byte 0x85
|
||||||
|
byte 0xf0
|
||||||
|
byte 0xff
|
||||||
|
byte 0xff
|
||||||
|
byte 0xff
|
||||||
|
|
||||||
|
; mov rbx, rax
|
||||||
|
byte 0x48
|
||||||
|
byte 0x89
|
||||||
|
byte 0xc3
|
||||||
|
|
||||||
|
; mov rax, [rbp-8]
|
||||||
|
byte 0x48
|
||||||
|
byte 0x8b
|
||||||
|
byte 0x85
|
||||||
|
byte 0xf8
|
||||||
|
byte 0xff
|
||||||
|
byte 0xff
|
||||||
|
byte 0xff
|
||||||
|
|
||||||
|
; xor edx, edx
|
||||||
|
byte 0x31
|
||||||
|
byte 0xd2
|
||||||
|
|
||||||
|
; div rbx
|
||||||
|
byte 0x48
|
||||||
|
byte 0xf7
|
||||||
|
byte 0xf3
|
||||||
|
|
||||||
|
; mov [rbp-40], rax
|
||||||
|
byte 0x48
|
||||||
|
byte 0x89
|
||||||
|
byte 0x85
|
||||||
|
byte 0xd8
|
||||||
|
byte 0xff
|
||||||
|
byte 0xff
|
||||||
|
byte 0xff
|
||||||
|
|
||||||
|
; mov rax, rdx
|
||||||
|
byte 0x48
|
||||||
|
byte 0x89
|
||||||
|
byte 0xd0
|
||||||
|
|
||||||
|
; mov [rbp-48], rax
|
||||||
|
byte 0x48
|
||||||
|
byte 0x89
|
||||||
|
byte 0x85
|
||||||
|
byte 0xd0
|
||||||
|
byte 0xff
|
||||||
|
byte 0xff
|
||||||
|
byte 0xff
|
||||||
|
|
||||||
|
*8p_quotient = q
|
||||||
|
*8p_remainder = r
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
; allows for negative shifts
|
; allows for negative shifts
|
||||||
function right_shift
|
function right_shift
|
||||||
argument x
|
argument x
|
||||||
|
@ -93,7 +162,8 @@ function free
|
||||||
syscall(11, psize, size)
|
syscall(11, psize, size)
|
||||||
return
|
return
|
||||||
|
|
||||||
; returns a pointer to a null-terminated string containing the number given
|
; returns a pointer to a null-terminated string containing the
|
||||||
|
; (unsigned) number given
|
||||||
function itos
|
function itos
|
||||||
global 32 itos_string
|
global 32 itos_string
|
||||||
argument x
|
argument x
|
||||||
|
@ -102,10 +172,9 @@ function itos
|
||||||
p = &itos_string
|
p = &itos_string
|
||||||
p += 30
|
p += 30
|
||||||
:itos_loop
|
:itos_loop
|
||||||
c = x % 10
|
divmod_unsigned(x, 10, &x, &c)
|
||||||
c += '0
|
c += '0
|
||||||
*1p = c
|
*1p = c
|
||||||
x /= 10
|
|
||||||
if x == 0 goto itos_loop_end
|
if x == 0 goto itos_loop_end
|
||||||
p -= 1
|
p -= 1
|
||||||
goto itos_loop
|
goto itos_loop
|
||||||
|
|
|
@ -137,6 +137,7 @@ In the table below, `IMM64` means a 64-bit *immediate* (a constant number).
|
||||||
│ add rax, rbx │ 48 01 d8 │ add rbx to rax │
|
│ add rax, rbx │ 48 01 d8 │ add rbx to rax │
|
||||||
│ sub rax, rbx │ 48 29 d8 │ subtract rbx from rax │
|
│ sub rax, rbx │ 48 29 d8 │ subtract rbx from rax │
|
||||||
│ imul rbx │ 48 f7 eb │ set rdx:rax to rax * rbx (signed) │
|
│ imul rbx │ 48 f7 eb │ set rdx:rax to rax * rbx (signed) │
|
||||||
|
│ cqo │ 48 99 │ sign-extend rax to rdx:rax |
|
||||||
│ idiv rbx │ 48 f7 fb │ divide rdx:rax by rbx (signed); put │
|
│ idiv rbx │ 48 f7 fb │ divide rdx:rax by rbx (signed); put │
|
||||||
│ │ │ quotient in rax, remainder in rbx │
|
│ │ │ quotient in rax, remainder in rbx │
|
||||||
│ mul rbx │ 48 f7 e3 │ like imul, but unsigned │
|
│ mul rbx │ 48 f7 e3 │ like imul, but unsigned │
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue