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
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_zero_rdx_idiv_rbx
|
||||
call :emit_cqo_idiv_rbx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
@ -1014,7 +1014,7 @@ align
|
|||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_zero_rdx_idiv_rbx
|
||||
call :emit_cqo_idiv_rbx
|
||||
call :set_rax_to_rdx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
|
@ -1475,11 +1475,11 @@ align
|
|||
|
||||
:rvalue_div
|
||||
call :set_rbx_to_rsi
|
||||
!:emit_zero_rdx_idiv_rbx
|
||||
!:emit_cqo_idiv_rbx
|
||||
|
||||
:rvalue_rem
|
||||
call :set_rbx_to_rsi
|
||||
call :emit_zero_rdx_idiv_rbx
|
||||
call :emit_cqo_idiv_rbx
|
||||
call :set_rax_to_rdx
|
||||
return
|
||||
|
||||
|
@ -1745,16 +1745,6 @@ align
|
|||
x31
|
||||
xc0
|
||||
|
||||
:zero_rdx
|
||||
J=d4
|
||||
I=:xor_edx_edx
|
||||
D=d2
|
||||
syscall x1
|
||||
return
|
||||
:xor_edx_edx
|
||||
x31
|
||||
xd2
|
||||
|
||||
:set_rbx_to_rax
|
||||
J=d4
|
||||
I=:mov_rbx_rax
|
||||
|
@ -2014,14 +2004,15 @@ align
|
|||
xf7
|
||||
xeb
|
||||
|
||||
:emit_zero_rdx_idiv_rbx
|
||||
call :zero_rdx
|
||||
:emit_cqo_idiv_rbx
|
||||
J=d4
|
||||
I=:idiv_rbx
|
||||
D=d3
|
||||
I=:cqo_idiv_rbx
|
||||
D=d5
|
||||
syscall x1
|
||||
return
|
||||
:idiv_rbx
|
||||
:cqo_idiv_rbx
|
||||
x48
|
||||
x99
|
||||
x48
|
||||
xf7
|
||||
xfb
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
; uchar kind (one of the constants below)
|
||||
; uchar info
|
||||
; 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
|
||||
; - for constant ints, the 64-bit integral value
|
||||
; - for constant floats, the 64-bit double value (even if expression has type float)
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
long double d;
|
||||
} (*x)(void);
|
||||
*/
|
||||
typedef long int unsigned Foo[3 * 3];
|
||||
typedef long int unsigned Foo[19 + (-3) % 187 - 28 + 5 * 6];
|
||||
|
|
42
05/parse.b
42
05/parse.b
|
@ -943,6 +943,7 @@ function evaluate_constant_expression
|
|||
argument p_value
|
||||
local a
|
||||
local b
|
||||
local p
|
||||
|
||||
if *1expr == EXPRESSION_CONSTANT_INT goto eval_constant_int
|
||||
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_LOGICAL_NOT goto eval_logical_not
|
||||
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_DIV goto eval_div
|
||||
if *1expr == EXPRESSION_REMAINDER goto eval_remainder
|
||||
byte 0xcc
|
||||
|
||||
:eval_todo
|
||||
|
@ -998,12 +1002,48 @@ function evaluate_constant_expression
|
|||
:eval_logical_not0
|
||||
*8p_value = 1
|
||||
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
|
||||
expr += 8
|
||||
expr = evaluate_constant_expression(expr, &a)
|
||||
expr = evaluate_constant_expression(expr, &b)
|
||||
*8p_value = a * b
|
||||
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
|
||||
function expr_binary_type_usual_conversions
|
||||
|
|
75
05/util.b
75
05/util.b
|
@ -25,6 +25,75 @@ function full_multiply_signed
|
|||
*8p_upper = upper
|
||||
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
|
||||
function right_shift
|
||||
argument x
|
||||
|
@ -93,7 +162,8 @@ function free
|
|||
syscall(11, psize, size)
|
||||
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
|
||||
global 32 itos_string
|
||||
argument x
|
||||
|
@ -102,10 +172,9 @@ function itos
|
|||
p = &itos_string
|
||||
p += 30
|
||||
:itos_loop
|
||||
c = x % 10
|
||||
divmod_unsigned(x, 10, &x, &c)
|
||||
c += '0
|
||||
*1p = c
|
||||
x /= 10
|
||||
if x == 0 goto itos_loop_end
|
||||
p -= 1
|
||||
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 │
|
||||
│ sub rax, rbx │ 48 29 d8 │ subtract rbx from rax │
|
||||
│ 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 │
|
||||
│ │ │ quotient in rax, remainder in rbx │
|
||||
│ mul rbx │ 48 f7 e3 │ like imul, but unsigned │
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue