more consterxprs

This commit is contained in:
pommicket 2022-01-21 23:24:18 -05:00
parent a7ace346b7
commit 08c49a193f
6 changed files with 127 additions and 26 deletions

29
04/in03
View file

@ -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

View file

@ -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)

View file

@ -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];

View file

@ -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,12 +1002,48 @@ 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

View file

@ -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

View file

@ -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 │