Support for long integer with byte code
This commit is contained in:
parent
0c9992f549
commit
3d9302c90c
540
include/crt.c
540
include/crt.c
|
@ -145,6 +145,58 @@ W1: dey
|
||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// divide accu by tmp result in accu, remainder in tmp + 4
|
||||||
|
|
||||||
|
__asm divmod32
|
||||||
|
{
|
||||||
|
sty tmpy
|
||||||
|
lda #0
|
||||||
|
sta tmp + 4
|
||||||
|
sta tmp + 5
|
||||||
|
sta tmp + 6
|
||||||
|
sta tmp + 7
|
||||||
|
ldy #32
|
||||||
|
clc
|
||||||
|
L1: rol accu
|
||||||
|
rol accu + 1
|
||||||
|
rol accu + 2
|
||||||
|
rol accu + 3
|
||||||
|
rol tmp + 4
|
||||||
|
rol tmp + 5
|
||||||
|
rol tmp + 6
|
||||||
|
rol tmp + 7
|
||||||
|
|
||||||
|
lda tmp + 4
|
||||||
|
cmp tmp + 0
|
||||||
|
lda tmp + 5
|
||||||
|
sbc tmp + 1
|
||||||
|
lda tmp + 6
|
||||||
|
sbc tmp + 2
|
||||||
|
lda tmp + 7
|
||||||
|
sbc tmp + 3
|
||||||
|
bcc W1
|
||||||
|
lda tmp + 4
|
||||||
|
sbc tmp + 0
|
||||||
|
sta tmp + 4
|
||||||
|
lda tmp + 5
|
||||||
|
sbc tmp + 1
|
||||||
|
sta tmp + 5
|
||||||
|
lda tmp + 6
|
||||||
|
sbc tmp + 2
|
||||||
|
sta tmp + 6
|
||||||
|
lda tmp + 7
|
||||||
|
sbc tmp + 3
|
||||||
|
sta tmp + 7
|
||||||
|
W1: dey
|
||||||
|
bne L1
|
||||||
|
rol accu
|
||||||
|
rol accu + 1
|
||||||
|
rol accu + 2
|
||||||
|
rol accu + 3
|
||||||
|
ldy tmpy
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
// Multiply accu by tmp result in tmp + 2
|
// Multiply accu by tmp result in tmp + 2
|
||||||
|
|
||||||
__asm mul16
|
__asm mul16
|
||||||
|
@ -2972,3 +3024,491 @@ W1: jsr fround.frup
|
||||||
|
|
||||||
#pragma bytecode(BC_OP_CEIL_F32, inp_op_ceil_f32)
|
#pragma bytecode(BC_OP_CEIL_F32, inp_op_ceil_f32)
|
||||||
|
|
||||||
|
__asm inp_op_extrt
|
||||||
|
{
|
||||||
|
lda (ip), y
|
||||||
|
iny
|
||||||
|
sta c1 + 1
|
||||||
|
lda (ip), y
|
||||||
|
iny
|
||||||
|
sta c1 + 2
|
||||||
|
lda (ip), y
|
||||||
|
iny
|
||||||
|
tax
|
||||||
|
c1: jsr $0000
|
||||||
|
jmp startup.exec
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_EXTRT, inp_op_extrt)
|
||||||
|
|
||||||
|
|
||||||
|
__asm inp_op_ext_u16
|
||||||
|
{
|
||||||
|
lda #0
|
||||||
|
sta accu + 2
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_CONV_U16_U32, inp_op_ext_u16)
|
||||||
|
|
||||||
|
|
||||||
|
__asm inp_op_ext_s16
|
||||||
|
{
|
||||||
|
lda accu + 1
|
||||||
|
ora #$7f
|
||||||
|
bmi w1
|
||||||
|
lda #0
|
||||||
|
w1:
|
||||||
|
sta accu + 2
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_CONV_I16_I32, inp_op_ext_s16)
|
||||||
|
|
||||||
|
__asm inp_op_invert_32
|
||||||
|
{
|
||||||
|
lda accu + 0
|
||||||
|
eor #$ff
|
||||||
|
sta accu + 0
|
||||||
|
lda accu + 1
|
||||||
|
eor #$ff
|
||||||
|
sta accu + 1
|
||||||
|
lda accu + 2
|
||||||
|
eor #$ff
|
||||||
|
sta accu + 2
|
||||||
|
lda accu + 3
|
||||||
|
eor #$ff
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_OP_INVERT_32, inp_op_invert_32)
|
||||||
|
|
||||||
|
__asm inp_op_negate_32
|
||||||
|
{
|
||||||
|
jmp negaccu
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_OP_NEGATE_32, inp_op_negate_32)
|
||||||
|
|
||||||
|
|
||||||
|
__asm inp_op_addr_32
|
||||||
|
{
|
||||||
|
clc
|
||||||
|
lda accu + 0
|
||||||
|
adc $00, x
|
||||||
|
sta accu + 0
|
||||||
|
lda accu + 1
|
||||||
|
adc $01, x
|
||||||
|
sta accu + 1
|
||||||
|
lda accu + 2
|
||||||
|
adc $02, x
|
||||||
|
sta accu + 2
|
||||||
|
lda accu + 3
|
||||||
|
adc $03, x
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_ADD_L32, inp_op_addr_32)
|
||||||
|
|
||||||
|
__asm inp_op_subr_32
|
||||||
|
{
|
||||||
|
sec
|
||||||
|
lda accu + 0
|
||||||
|
sbc $00, x
|
||||||
|
sta accu + 0
|
||||||
|
lda accu + 1
|
||||||
|
sbc $01, x
|
||||||
|
sta accu + 1
|
||||||
|
lda accu + 2
|
||||||
|
sbc $02, x
|
||||||
|
sta accu + 2
|
||||||
|
lda accu + 3
|
||||||
|
sbc $03, x
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_SUB_L32, inp_op_subr_32)
|
||||||
|
|
||||||
|
__asm inp_op_andr_32
|
||||||
|
{
|
||||||
|
lda accu + 0
|
||||||
|
and $00, x
|
||||||
|
sta accu + 0
|
||||||
|
lda accu + 1
|
||||||
|
and $01, x
|
||||||
|
sta accu + 1
|
||||||
|
lda accu + 2
|
||||||
|
and $02, x
|
||||||
|
sta accu + 2
|
||||||
|
lda accu + 3
|
||||||
|
and $03, x
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_AND_L32, inp_op_andr_32)
|
||||||
|
|
||||||
|
__asm inp_op_orr_32
|
||||||
|
{
|
||||||
|
lda accu + 0
|
||||||
|
ora $00, x
|
||||||
|
sta accu + 0
|
||||||
|
lda accu + 1
|
||||||
|
ora $01, x
|
||||||
|
sta accu + 1
|
||||||
|
lda accu + 2
|
||||||
|
ora $02, x
|
||||||
|
sta accu + 2
|
||||||
|
lda accu + 3
|
||||||
|
ora $03, x
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_OR_L32, inp_op_orr_32)
|
||||||
|
|
||||||
|
__asm inp_op_xorr_32
|
||||||
|
{
|
||||||
|
lda accu + 0
|
||||||
|
eor $00, x
|
||||||
|
sta accu + 0
|
||||||
|
lda accu + 1
|
||||||
|
eor $01, x
|
||||||
|
sta accu + 1
|
||||||
|
lda accu + 2
|
||||||
|
eor $02, x
|
||||||
|
sta accu + 2
|
||||||
|
lda accu + 3
|
||||||
|
eor $03, x
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_XOR_L32, inp_op_xorr_32)
|
||||||
|
|
||||||
|
__asm inp_op_mulr_32
|
||||||
|
{
|
||||||
|
lda #0
|
||||||
|
sta tmp + 4
|
||||||
|
sta tmp + 5
|
||||||
|
sta tmp + 6
|
||||||
|
sta tmp + 7
|
||||||
|
|
||||||
|
lda $00, x
|
||||||
|
sta tmp + 0
|
||||||
|
lda $01, x
|
||||||
|
sta tmp + 1
|
||||||
|
lda $02, x
|
||||||
|
sta tmp + 2
|
||||||
|
lda $03, x
|
||||||
|
sta tmp + 3
|
||||||
|
ldx #32
|
||||||
|
L1: lsr tmp + 3
|
||||||
|
ror tmp + 2
|
||||||
|
ror tmp + 1
|
||||||
|
ror tmp + 0
|
||||||
|
bcc W1
|
||||||
|
clc
|
||||||
|
lda tmp + 4
|
||||||
|
adc accu
|
||||||
|
sta tmp + 4
|
||||||
|
lda tmp + 5
|
||||||
|
adc accu + 1
|
||||||
|
sta tmp + 5
|
||||||
|
lda tmp + 6
|
||||||
|
adc accu + 2
|
||||||
|
sta tmp + 6
|
||||||
|
lda tmp + 7
|
||||||
|
adc accu + 3
|
||||||
|
sta tmp + 7
|
||||||
|
W1: asl accu
|
||||||
|
rol accu + 1
|
||||||
|
rol accu + 2
|
||||||
|
rol accu + 3
|
||||||
|
dex
|
||||||
|
bne L1
|
||||||
|
lda tmp + 4
|
||||||
|
sta accu
|
||||||
|
lda tmp + 5
|
||||||
|
sta accu + 1
|
||||||
|
lda tmp + 6
|
||||||
|
sta accu + 2
|
||||||
|
lda tmp + 7
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_MUL_L32, inp_op_mulr_32)
|
||||||
|
|
||||||
|
__asm negaccu32
|
||||||
|
{
|
||||||
|
sec
|
||||||
|
lda #0
|
||||||
|
sbc accu
|
||||||
|
sta accu
|
||||||
|
lda #0
|
||||||
|
sbc accu + 1
|
||||||
|
sta accu + 1
|
||||||
|
lda #0
|
||||||
|
sbc accu + 2
|
||||||
|
sta accu + 2
|
||||||
|
lda #0
|
||||||
|
sbc accu + 3
|
||||||
|
sta accu + 3
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
__asm negtmp32
|
||||||
|
{
|
||||||
|
sec
|
||||||
|
lda #0
|
||||||
|
sbc tmp
|
||||||
|
sta tmp
|
||||||
|
lda #0
|
||||||
|
sbc tmp + 1
|
||||||
|
sta tmp + 1
|
||||||
|
lda #0
|
||||||
|
sbc tmp + 2
|
||||||
|
sta tmp + 2
|
||||||
|
lda #0
|
||||||
|
sbc tmp + 3
|
||||||
|
sta tmp + 3
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
__asm inp_binop_div_u32
|
||||||
|
{
|
||||||
|
lda $00, x
|
||||||
|
sta tmp + 0
|
||||||
|
lda $01, x
|
||||||
|
sta tmp + 1
|
||||||
|
lda $02, x
|
||||||
|
sta tmp + 2
|
||||||
|
lda $03, x
|
||||||
|
sta tmp + 3
|
||||||
|
jsr divmod32
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_DIV_U32, inp_binop_div_u32)
|
||||||
|
|
||||||
|
__asm inp_binop_mod_u32
|
||||||
|
{
|
||||||
|
lda $00, x
|
||||||
|
sta tmp + 0
|
||||||
|
lda $01, x
|
||||||
|
sta tmp + 1
|
||||||
|
lda $02, x
|
||||||
|
sta tmp + 2
|
||||||
|
lda $03, x
|
||||||
|
sta tmp + 3
|
||||||
|
jsr divmod32
|
||||||
|
lda tmp + 4
|
||||||
|
sta accu
|
||||||
|
lda tmp + 5
|
||||||
|
sta accu + 1
|
||||||
|
lda tmp + 6
|
||||||
|
sta accu + 2
|
||||||
|
lda tmp + 7
|
||||||
|
sta accu + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_MOD_U32, inp_binop_mod_u32)
|
||||||
|
|
||||||
|
__asm inp_binop_div_s32
|
||||||
|
{
|
||||||
|
lda $00, x
|
||||||
|
sta tmp + 0
|
||||||
|
lda $01, x
|
||||||
|
sta tmp + 1
|
||||||
|
lda $02, x
|
||||||
|
sta tmp + 2
|
||||||
|
lda $03, x
|
||||||
|
sta tmp + 3
|
||||||
|
bit accu + 3
|
||||||
|
bpl L1
|
||||||
|
jsr negaccu32
|
||||||
|
bit tmp + 3
|
||||||
|
bpl L2
|
||||||
|
jsr negtmp32
|
||||||
|
L3: jsr divmod32
|
||||||
|
rts
|
||||||
|
L1: bit tmp + 3
|
||||||
|
bpl L3
|
||||||
|
jsr negtmp32
|
||||||
|
L2: jsr divmod32
|
||||||
|
jsr negaccu32
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_DIV_I32, inp_binop_div_s32)
|
||||||
|
|
||||||
|
__asm inp_binop_mod_s32
|
||||||
|
{
|
||||||
|
lda $00, x
|
||||||
|
sta tmp + 0
|
||||||
|
lda $01, x
|
||||||
|
sta tmp + 1
|
||||||
|
lda $02, x
|
||||||
|
sta tmp + 2
|
||||||
|
lda $03, x
|
||||||
|
sta tmp + 3
|
||||||
|
bit accu + 3
|
||||||
|
bpl L1
|
||||||
|
jsr negaccu32
|
||||||
|
bit tmp + 3
|
||||||
|
bpl L2
|
||||||
|
jsr negtmp32
|
||||||
|
L3: jsr divmod32
|
||||||
|
lda tmp + 4
|
||||||
|
sta accu
|
||||||
|
lda tmp + 5
|
||||||
|
sta accu + 1
|
||||||
|
lda tmp + 6
|
||||||
|
sta accu + 2
|
||||||
|
lda tmp + 7
|
||||||
|
sta accu + 3
|
||||||
|
rts
|
||||||
|
L1: bit tmp + 3
|
||||||
|
bpl L3
|
||||||
|
jsr negtmp32
|
||||||
|
L2: jsr divmod32
|
||||||
|
lda tmp + 4
|
||||||
|
sta accu
|
||||||
|
lda tmp + 5
|
||||||
|
sta accu + 1
|
||||||
|
lda tmp + 6
|
||||||
|
sta accu + 2
|
||||||
|
lda tmp + 7
|
||||||
|
sta accu + 3
|
||||||
|
jsr negaccu32
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_MOD_I32, inp_binop_mod_s32)
|
||||||
|
|
||||||
|
__asm inp_op_shl_l32
|
||||||
|
{
|
||||||
|
lda $00, x
|
||||||
|
and #31
|
||||||
|
beq W1
|
||||||
|
tax
|
||||||
|
lda accu + 0
|
||||||
|
L1: asl
|
||||||
|
rol accu + 1
|
||||||
|
rol accu + 2
|
||||||
|
rol accu + 3
|
||||||
|
dex
|
||||||
|
bne L1
|
||||||
|
sta accu + 0
|
||||||
|
W1:
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_SHL_L32, inp_op_shl_l32)
|
||||||
|
|
||||||
|
|
||||||
|
__asm inp_op_shr_u32
|
||||||
|
{
|
||||||
|
lda $00, x
|
||||||
|
and #31
|
||||||
|
beq W1
|
||||||
|
tax
|
||||||
|
lda accu + 3
|
||||||
|
L1: lsr
|
||||||
|
ror accu + 2
|
||||||
|
ror accu + 1
|
||||||
|
ror accu + 0
|
||||||
|
dex
|
||||||
|
bne L1
|
||||||
|
sta accu + 3
|
||||||
|
W1:
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_SHR_U32, inp_op_shr_u32)
|
||||||
|
|
||||||
|
__asm inp_op_shr_s32
|
||||||
|
{
|
||||||
|
lda $00, x
|
||||||
|
and #31
|
||||||
|
beq W1
|
||||||
|
tax
|
||||||
|
lda accu + 3
|
||||||
|
L1: cmp #$80
|
||||||
|
ror
|
||||||
|
ror accu + 2
|
||||||
|
ror accu + 1
|
||||||
|
ror accu + 0
|
||||||
|
dex
|
||||||
|
bne L1
|
||||||
|
sta accu + 3
|
||||||
|
W1:
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_SHR_I32, inp_op_shr_s32)
|
||||||
|
|
||||||
|
__asm inp_op_cmp_u32
|
||||||
|
{
|
||||||
|
lda $03, x
|
||||||
|
cmp accu + 3
|
||||||
|
bne cmpne
|
||||||
|
lda $02, x
|
||||||
|
cmp accu + 2
|
||||||
|
bne cmpne
|
||||||
|
lda $01, x
|
||||||
|
cmp accu + 1
|
||||||
|
bne cmpne
|
||||||
|
lda $00 , x
|
||||||
|
cmp accu
|
||||||
|
bne cmpne
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta accu
|
||||||
|
sta accu + 1
|
||||||
|
rts
|
||||||
|
cmp_lt:
|
||||||
|
lda #$ff
|
||||||
|
sta accu
|
||||||
|
sta accu +1
|
||||||
|
rts
|
||||||
|
cmpne:
|
||||||
|
bcc cmp_lt
|
||||||
|
lda #1
|
||||||
|
sta accu
|
||||||
|
lda #0
|
||||||
|
sta accu + 1
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_CMP_U32, inp_op_cmp_u32)
|
||||||
|
|
||||||
|
__asm inp_op_cmp_s32
|
||||||
|
{
|
||||||
|
lda accu + 3
|
||||||
|
eor #$80
|
||||||
|
sta accu + 3
|
||||||
|
lda $03, x
|
||||||
|
eor #$80
|
||||||
|
cmp accu + 3
|
||||||
|
bne cmpne
|
||||||
|
lda $02, x
|
||||||
|
cmp accu + 2
|
||||||
|
bne cmpne
|
||||||
|
lda $01, x
|
||||||
|
cmp accu + 1
|
||||||
|
bne cmpne
|
||||||
|
lda $00 , x
|
||||||
|
cmp accu
|
||||||
|
bne cmpne
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta accu
|
||||||
|
sta accu + 1
|
||||||
|
rts
|
||||||
|
cmp_lt:
|
||||||
|
lda #$ff
|
||||||
|
sta accu
|
||||||
|
sta accu +1
|
||||||
|
rts
|
||||||
|
cmpne:
|
||||||
|
bcc cmp_lt
|
||||||
|
lda #1
|
||||||
|
sta accu
|
||||||
|
lda #0
|
||||||
|
sta accu + 1
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_BINOP_CMP_S32, inp_op_cmp_s32)
|
||||||
|
|
|
@ -161,7 +161,31 @@ enum ByteCode
|
||||||
BC_COPY,
|
BC_COPY,
|
||||||
BC_COPY_LONG,
|
BC_COPY_LONG,
|
||||||
|
|
||||||
BC_NATIVE = 0x75
|
BC_EXTRT,
|
||||||
|
|
||||||
|
BC_NATIVE = 0x75,
|
||||||
|
|
||||||
|
BC_CONV_I16_I32 = 0x80,
|
||||||
|
BC_CONV_U16_U32,
|
||||||
|
|
||||||
|
BC_OP_NEGATE_32,
|
||||||
|
BC_OP_INVERT_32,
|
||||||
|
|
||||||
|
BC_BINOP_ADD_L32,
|
||||||
|
BC_BINOP_SUB_L32,
|
||||||
|
BC_BINOP_AND_L32,
|
||||||
|
BC_BINOP_OR_L32,
|
||||||
|
BC_BINOP_XOR_L32,
|
||||||
|
BC_BINOP_MUL_L32,
|
||||||
|
BC_BINOP_DIV_U32,
|
||||||
|
BC_BINOP_MOD_U32,
|
||||||
|
BC_BINOP_DIV_I32,
|
||||||
|
BC_BINOP_MOD_I32,
|
||||||
|
BC_BINOP_SHL_L32,
|
||||||
|
BC_BINOP_SHR_U32,
|
||||||
|
BC_BINOP_SHR_I32,
|
||||||
|
BC_BINOP_CMP_U32,
|
||||||
|
BC_BINOP_CMP_S32,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
void itoa(int n, char * s, int radix)
|
void itoa(int n, char * s, unsigned radix)
|
||||||
{
|
{
|
||||||
bool neg = n < 0;
|
bool neg = n < 0;
|
||||||
if (neg)
|
if (neg)
|
||||||
|
@ -35,7 +35,7 @@ void itoa(int n, char * s, int radix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void utoa(unsigned int n, char * s, unsigned int radix)
|
void utoa(unsigned int n, char * s, unsigned radix)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -57,6 +57,61 @@ void utoa(unsigned int n, char * s, unsigned int radix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ltoa(long n, char * s, unsigned radix)
|
||||||
|
{
|
||||||
|
bool neg = n < 0;
|
||||||
|
if (neg)
|
||||||
|
{
|
||||||
|
n = - n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
int d = n % radix;
|
||||||
|
if (d < 10)
|
||||||
|
d += '0';
|
||||||
|
else
|
||||||
|
d += 'A' - 10;
|
||||||
|
s[i++] = d;
|
||||||
|
} while ((n /= radix) > 0);
|
||||||
|
|
||||||
|
if (neg)
|
||||||
|
{
|
||||||
|
s[i++] = '-';
|
||||||
|
}
|
||||||
|
s[i] = 0;
|
||||||
|
int j = 0;
|
||||||
|
while (j + 1 < i)
|
||||||
|
{
|
||||||
|
char c = s[j];
|
||||||
|
s[j++] = s[--i];
|
||||||
|
s[i] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ultoa(unsigned long n, char * s, unsigned radix)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
unsigned int d = n % radix;
|
||||||
|
if (d < 10)
|
||||||
|
d += '0';
|
||||||
|
else
|
||||||
|
d += 'A' - 10;
|
||||||
|
s[i++] = d;
|
||||||
|
} while ((n /= radix) > 0);
|
||||||
|
|
||||||
|
s[i] = 0;
|
||||||
|
int j = 0;
|
||||||
|
while (j + 1 < i)
|
||||||
|
{
|
||||||
|
char c = s[j];
|
||||||
|
s[j++] = s[--i];
|
||||||
|
s[i] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ftoa(float f, char * s)
|
void ftoa(float f, char * s)
|
||||||
{
|
{
|
||||||
if (f < 0.0)
|
if (f < 0.0)
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
#ifndef STDLIB_H
|
#ifndef STDLIB_H
|
||||||
#define STDLIB_H
|
#define STDLIB_H
|
||||||
|
|
||||||
void itoa(int n, char * s, int radix);
|
void itoa(int n, char * s, unsigned radix);
|
||||||
|
|
||||||
void utoa(unsigned int n, char * s, unsigned int radix);
|
void utoa(unsigned int n, char * s, unsigned radix);
|
||||||
|
|
||||||
void ftoa(float f, char * s);
|
void ftoa(float f, char * s);
|
||||||
|
|
||||||
|
void ltoa(long n, char * s, unsigned radix);
|
||||||
|
|
||||||
|
void ultoa(unsigned long n, char * s, unsigned radix);
|
||||||
|
|
||||||
int atoi(const char * s);
|
int atoi(const char * s);
|
||||||
|
|
||||||
float atof(const char * s);
|
float atof(const char * s);
|
||||||
|
|
||||||
|
|
||||||
void exit(int status);
|
void exit(int status);
|
||||||
|
|
||||||
void * malloc(unsigned int size);
|
void * malloc(unsigned int size);
|
||||||
|
|
|
@ -102,6 +102,9 @@ bool ByteCodeInstruction::IsCommutative(void) const
|
||||||
if (mCode == BC_BINOP_ADD_F32 || mCode == BC_BINOP_MUL_F32)
|
if (mCode == BC_BINOP_ADD_F32 || mCode == BC_BINOP_MUL_F32)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (mCode == BC_BINOP_ADD_L32 || mCode == BC_BINOP_AND_L32 || mCode == BC_BINOP_OR_L32 || mCode == BC_BINOP_XOR_L32 || mCode == BC_BINOP_MUL_L32)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +194,8 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
|
||||||
return true;
|
return true;
|
||||||
if (mCode == BC_JSR || mCode == BC_CALL)
|
if (mCode == BC_JSR || mCode == BC_CALL)
|
||||||
return true;
|
return true;
|
||||||
|
if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reg == BC_REG_ADDR)
|
if (reg == BC_REG_ADDR)
|
||||||
|
@ -495,6 +500,39 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BC_CONV_I16_I32:
|
||||||
|
case BC_CONV_U16_U32:
|
||||||
|
case BC_OP_NEGATE_32:
|
||||||
|
case BC_OP_INVERT_32:
|
||||||
|
case BC_BINOP_ADD_L32:
|
||||||
|
case BC_BINOP_SUB_L32:
|
||||||
|
case BC_BINOP_AND_L32:
|
||||||
|
case BC_BINOP_OR_L32:
|
||||||
|
case BC_BINOP_XOR_L32:
|
||||||
|
case BC_BINOP_MUL_L32:
|
||||||
|
case BC_BINOP_DIV_U32:
|
||||||
|
case BC_BINOP_MOD_U32:
|
||||||
|
case BC_BINOP_DIV_I32:
|
||||||
|
case BC_BINOP_MOD_I32:
|
||||||
|
case BC_BINOP_SHL_L32:
|
||||||
|
case BC_BINOP_SHR_U32:
|
||||||
|
case BC_BINOP_SHR_I32:
|
||||||
|
case BC_BINOP_CMP_U32:
|
||||||
|
case BC_BINOP_CMP_S32:
|
||||||
|
{
|
||||||
|
block->PutCode(generator, BC_EXTRT);
|
||||||
|
|
||||||
|
LinkerReference rl;
|
||||||
|
rl.mOffset = block->mCode.Size();
|
||||||
|
rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
|
||||||
|
rl.mRefObject = generator->mExtByteCodes[mCode - 128];
|
||||||
|
rl.mRefOffset = 0;
|
||||||
|
block->mRelocations.Push(rl);
|
||||||
|
block->PutWord(0);
|
||||||
|
block->PutByte(mRegister);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
@ -570,6 +608,22 @@ void ByteCodeBasicBlock::IntConstToAccu(int64 val)
|
||||||
mIns.Push(ins);
|
mIns.Push(ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ByteCodeBasicBlock::LongConstToAccu(int64 val)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_CONST_32);
|
||||||
|
bins.mRegister = BC_REG_ACCU;
|
||||||
|
bins.mValue = int(val);
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ByteCodeBasicBlock::LongConstToWork(int64 val)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_CONST_32);
|
||||||
|
bins.mRegister = BC_REG_WORK;
|
||||||
|
bins.mValue = int(val);
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
|
||||||
void ByteCodeBasicBlock::FloatConstToAccu(double val)
|
void ByteCodeBasicBlock::FloatConstToAccu(double val)
|
||||||
{
|
{
|
||||||
union { float f; int v; } cc;
|
union { float f; int v; } cc;
|
||||||
|
@ -666,6 +720,13 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
|
||||||
bins.mValue = ins->mIntValue;
|
bins.mValue = ins->mIntValue;
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
}
|
}
|
||||||
|
else if (ins->mTType == IT_INT32)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_CONST_32);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
bins.mValue = ins->mIntValue;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ByteCodeInstruction bins(BC_CONST_16);
|
ByteCodeInstruction bins(BC_CONST_16);
|
||||||
|
@ -1005,7 +1066,10 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
||||||
{
|
{
|
||||||
if (ins->mSTemp[0] < 0)
|
if (ins->mSTemp[0] < 0)
|
||||||
{
|
{
|
||||||
|
if (ins->mOperandSize <= 2)
|
||||||
IntConstToAccu(ins->mSIntConst[0]);
|
IntConstToAccu(ins->mSIntConst[0]);
|
||||||
|
else
|
||||||
|
LongConstToAccu(ins->mSIntConst[0]);
|
||||||
|
|
||||||
if (ins->mOperandSize == 1)
|
if (ins->mOperandSize == 1)
|
||||||
{
|
{
|
||||||
|
@ -1113,6 +1177,59 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ins->mOperandSize == 4)
|
||||||
|
{
|
||||||
|
if (ins->mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_ABS_32);
|
||||||
|
bins.mRelocate = true;
|
||||||
|
bins.mLinkerObject = ins->mLinkerObject;
|
||||||
|
bins.mValue = ins->mSIntConst[1];
|
||||||
|
bins.mRegister = BC_REG_ACCU;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else if (ins->mMemory == IM_ABSOLUTE)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_ABS_32);
|
||||||
|
bins.mValue = ins->mSIntConst[1];
|
||||||
|
bins.mRegister = BC_REG_ACCU;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM)
|
||||||
|
{
|
||||||
|
int index = ins->mSIntConst[1];
|
||||||
|
if (ins->mMemory == IM_LOCAL)
|
||||||
|
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||||
|
else
|
||||||
|
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||||
|
|
||||||
|
if (index <= 252)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_LOCAL_32);
|
||||||
|
bins.mRegister = BC_REG_ACCU;
|
||||||
|
bins.mValue = index;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LEA_LOCAL);
|
||||||
|
lins.mRegister = BC_REG_ADDR;
|
||||||
|
lins.mValue = index;
|
||||||
|
mIns.Push(lins);
|
||||||
|
ByteCodeInstruction bins(BC_STORE_ADDR_32);
|
||||||
|
bins.mRegister = BC_REG_ACCU;
|
||||||
|
bins.mValue = 0;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ins->mMemory == IM_FRAME)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_FRAME_32);
|
||||||
|
bins.mRegister = BC_REG_ACCU;
|
||||||
|
bins.mValue = ins->mVarIndex + ins->mSIntConst[1] + 2;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1232,13 +1349,74 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ins->mOperandSize == 4)
|
||||||
|
{
|
||||||
|
if (ins->mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_ABS_32);
|
||||||
|
bins.mRelocate = true;
|
||||||
|
bins.mLinkerObject = ins->mLinkerObject;
|
||||||
|
bins.mValue = ins->mSIntConst[1];
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
bins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else if (ins->mMemory == IM_ABSOLUTE)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_ABS_32);
|
||||||
|
bins.mValue = ins->mSIntConst[1];
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
bins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM)
|
||||||
|
{
|
||||||
|
int index = ins->mSIntConst[1];
|
||||||
|
if (ins->mMemory == IM_LOCAL)
|
||||||
|
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||||
|
else
|
||||||
|
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||||
|
|
||||||
|
if (index <= 252)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_LOCAL_32);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
bins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
bins.mValue = index;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LEA_LOCAL);
|
||||||
|
lins.mRegister = BC_REG_ADDR;
|
||||||
|
lins.mValue = index;
|
||||||
|
mIns.Push(lins);
|
||||||
|
ByteCodeInstruction bins(BC_STORE_ADDR_32);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
bins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
bins.mValue = 0;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ins->mMemory == IM_FRAME)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_FRAME_32);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
bins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
bins.mValue = ins->mVarIndex + ins->mSIntConst[1] + 2;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ins->mSTemp[0] < 0)
|
if (ins->mSTemp[0] < 0)
|
||||||
{
|
{
|
||||||
|
if (ins->mOperandSize <= 2)
|
||||||
IntConstToAccu(ins->mSIntConst[0]);
|
IntConstToAccu(ins->mSIntConst[0]);
|
||||||
|
else
|
||||||
|
LongConstToAccu(ins->mSIntConst[0]);
|
||||||
|
|
||||||
if (ins->mMemory == IM_INDIRECT)
|
if (ins->mMemory == IM_INDIRECT)
|
||||||
{
|
{
|
||||||
|
@ -1260,6 +1438,13 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
||||||
bins.mValue = ins->mSIntConst[1];
|
bins.mValue = ins->mSIntConst[1];
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
}
|
}
|
||||||
|
else if (ins->mOperandSize == 4)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_ADDR_32);
|
||||||
|
bins.mRegister = BC_REG_ACCU;
|
||||||
|
bins.mValue = ins->mSIntConst[1];
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1286,6 +1471,14 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
||||||
bins.mValue = ins->mSIntConst[1];
|
bins.mValue = ins->mSIntConst[1];
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
}
|
}
|
||||||
|
else if (ins->mOperandSize == 4)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_ADDR_32);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
bins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
bins.mValue = ins->mSIntConst[1];
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1516,6 +1709,52 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ins->mOperandSize == 4)
|
||||||
|
{
|
||||||
|
if (ins->mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_LOAD_ABS_32);
|
||||||
|
bins.mRelocate = true;
|
||||||
|
bins.mLinkerObject = ins->mLinkerObject;
|
||||||
|
bins.mValue = ins->mSIntConst[0];
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else if (ins->mMemory == IM_ABSOLUTE)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_LOAD_ABS_32);
|
||||||
|
bins.mValue = ins->mSIntConst[0];
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM)
|
||||||
|
{
|
||||||
|
int index = ins->mSIntConst[0];
|
||||||
|
if (ins->mMemory == IM_LOCAL)
|
||||||
|
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||||
|
else
|
||||||
|
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||||
|
|
||||||
|
if (index <= 252)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_LOAD_LOCAL_32);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
bins.mValue = index;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LEA_LOCAL);
|
||||||
|
lins.mRegister = BC_REG_ADDR;
|
||||||
|
lins.mValue = index;
|
||||||
|
mIns.Push(lins);
|
||||||
|
ByteCodeInstruction bins(BC_LOAD_ADDR_32);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
bins.mValue = 0;
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1540,6 +1779,13 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
||||||
bins.mValue = ins->mSIntConst[0];
|
bins.mValue = ins->mSIntConst[0];
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
}
|
}
|
||||||
|
else if (ins->mOperandSize == 4)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction bins(BC_LOAD_ADDR_32);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
bins.mValue = ins->mSIntConst[0];
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1745,6 +1991,38 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
|
||||||
cins.mRegisterFinal = ins->mSFinal[1];
|
cins.mRegisterFinal = ins->mSFinal[1];
|
||||||
mIns.Push(cins);
|
mIns.Push(cins);
|
||||||
}
|
}
|
||||||
|
else if (ins->mSType[0] == IT_INT32)
|
||||||
|
{
|
||||||
|
if (ins->mSTemp[0] < 0)
|
||||||
|
{
|
||||||
|
LongConstToAccu(ins->mSIntConst[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||||
|
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
lins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
mIns.Push(lins);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ByteCodeInstruction cins(BC_BINOP_CMP_U32);
|
||||||
|
if (csigned)
|
||||||
|
cins.mCode = BC_BINOP_CMP_S32;
|
||||||
|
|
||||||
|
if (ins->mSTemp[1] < 0)
|
||||||
|
{
|
||||||
|
LongConstToWork(ins->mSIntConst[1]);
|
||||||
|
cins.mRegister = BC_REG_WORK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]];
|
||||||
|
}
|
||||||
|
|
||||||
|
cins.mRegisterFinal = ins->mSFinal[1];
|
||||||
|
mIns.Push(cins);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ins->mSTemp[1] < 0)
|
if (ins->mSTemp[1] < 0)
|
||||||
|
@ -1828,6 +2106,29 @@ static ByteCode ByteCodeBinRegOperator(const InterInstruction * ins)
|
||||||
return BC_EXIT;
|
return BC_EXIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ins->mTType == IT_INT32)
|
||||||
|
{
|
||||||
|
switch (ins->mOperator)
|
||||||
|
{
|
||||||
|
case IA_ADD: return BC_BINOP_ADD_L32;
|
||||||
|
case IA_SUB: return BC_BINOP_SUB_L32;
|
||||||
|
case IA_MUL: return BC_BINOP_MUL_L32;
|
||||||
|
case IA_DIVU: return BC_BINOP_DIV_U32;
|
||||||
|
case IA_MODU: return BC_BINOP_MOD_U32;
|
||||||
|
case IA_DIVS: return BC_BINOP_DIV_I32;
|
||||||
|
case IA_MODS: return BC_BINOP_MOD_I32;
|
||||||
|
case IA_AND: return BC_BINOP_AND_L32;
|
||||||
|
case IA_OR: return BC_BINOP_OR_L32;
|
||||||
|
case IA_XOR: return BC_BINOP_XOR_L32;
|
||||||
|
|
||||||
|
case IA_SHL: return BC_BINOP_SHL_L32;
|
||||||
|
case IA_SHR: return BC_BINOP_SHR_U32;
|
||||||
|
case IA_SAR: return BC_BINOP_SHR_I32;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return BC_EXIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (ins->mOperator)
|
switch (ins->mOperator)
|
||||||
|
@ -1972,7 +2273,38 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
||||||
mIns.Push(sins);
|
mIns.Push(sins);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case IA_EXT16TO32S:
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||||
|
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
lins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
mIns.Push(lins);
|
||||||
|
|
||||||
|
ByteCodeInstruction cins(BC_CONV_I16_I32);
|
||||||
|
cins.mRegister = 0;
|
||||||
|
mIns.Push(cins);
|
||||||
|
|
||||||
|
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||||
|
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
mIns.Push(sins);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case IA_EXT16TO32U:
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||||
|
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
lins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
mIns.Push(lins);
|
||||||
|
|
||||||
|
ByteCodeInstruction cins(BC_CONV_U16_U32);
|
||||||
|
cins.mRuntime = "lextu16";
|
||||||
|
cins.mRegister = 0;
|
||||||
|
mIns.Push(cins);
|
||||||
|
|
||||||
|
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||||
|
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
mIns.Push(sins);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2013,6 +2345,31 @@ void ByteCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterInst
|
||||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
mIns.Push(sins);
|
mIns.Push(sins);
|
||||||
}
|
}
|
||||||
|
else if (ins->mTType == IT_INT32)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||||
|
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
lins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
mIns.Push(lins);
|
||||||
|
|
||||||
|
switch (ins->mOperator)
|
||||||
|
{
|
||||||
|
case IA_NEG:
|
||||||
|
{
|
||||||
|
ByteCodeInstruction oins(BC_OP_NEGATE_32);
|
||||||
|
mIns.Push(oins);
|
||||||
|
} break;
|
||||||
|
case IA_NOT:
|
||||||
|
{
|
||||||
|
ByteCodeInstruction oins(BC_OP_INVERT_32);
|
||||||
|
mIns.Push(oins);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||||
|
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
mIns.Push(sins);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||||
|
@ -2078,6 +2435,41 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns
|
||||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
mIns.Push(sins);
|
mIns.Push(sins);
|
||||||
}
|
}
|
||||||
|
else if (ins->mTType == IT_INT32)
|
||||||
|
{
|
||||||
|
ByteCode bc = ByteCodeBinRegOperator(ins);
|
||||||
|
|
||||||
|
if (ins->mSTemp[1] < 0)
|
||||||
|
{
|
||||||
|
LongConstToAccu(ins->mSIntConst[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||||
|
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]];
|
||||||
|
lins.mRegisterFinal = ins->mSFinal[1];
|
||||||
|
mIns.Push(lins);
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteCodeInstruction bins(bc);
|
||||||
|
|
||||||
|
if (ins->mSTemp[0] < 0)
|
||||||
|
{
|
||||||
|
LongConstToWork(ins->mSIntConst[0]);
|
||||||
|
bins.mRegister = BC_REG_WORK;
|
||||||
|
}
|
||||||
|
else if (ins->mSTemp[1] == ins->mSTemp[0])
|
||||||
|
bins.mRegister = BC_REG_ACCU;
|
||||||
|
else
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||||
|
|
||||||
|
bins.mRegisterFinal = ins->mSFinal[0];
|
||||||
|
mIns.Push(bins);
|
||||||
|
|
||||||
|
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||||
|
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||||
|
mIns.Push(sins);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (ins->mOperator)
|
switch (ins->mOperator)
|
||||||
|
@ -3312,7 +3704,10 @@ ByteCodeGenerator::ByteCodeGenerator(Errors* errors, Linker* linker)
|
||||||
: mErrors(errors), mLinker(linker)
|
: mErrors(errors), mLinker(linker)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 128; i++)
|
for (int i = 0; i < 128; i++)
|
||||||
|
{
|
||||||
mByteCodeUsed[i] = false;
|
mByteCodeUsed[i] = false;
|
||||||
|
mExtByteCodes[i] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
mByteCodeUsed[BC_LEA_ABS] = true;
|
mByteCodeUsed[BC_LEA_ABS] = true;
|
||||||
mByteCodeUsed[BC_CALL] = true;
|
mByteCodeUsed[BC_CALL] = true;
|
||||||
|
|
|
@ -151,7 +151,31 @@ enum ByteCode
|
||||||
BC_COPY,
|
BC_COPY,
|
||||||
BC_COPY_LONG,
|
BC_COPY_LONG,
|
||||||
|
|
||||||
BC_NATIVE = 0x75
|
BC_EXTRT,
|
||||||
|
|
||||||
|
BC_NATIVE = 0x75,
|
||||||
|
|
||||||
|
BC_CONV_I16_I32 = 0x80,
|
||||||
|
BC_CONV_U16_U32,
|
||||||
|
|
||||||
|
BC_OP_NEGATE_32,
|
||||||
|
BC_OP_INVERT_32,
|
||||||
|
|
||||||
|
BC_BINOP_ADD_L32,
|
||||||
|
BC_BINOP_SUB_L32,
|
||||||
|
BC_BINOP_AND_L32,
|
||||||
|
BC_BINOP_OR_L32,
|
||||||
|
BC_BINOP_XOR_L32,
|
||||||
|
BC_BINOP_MUL_L32,
|
||||||
|
BC_BINOP_DIV_U32,
|
||||||
|
BC_BINOP_MOD_U32,
|
||||||
|
BC_BINOP_DIV_I32,
|
||||||
|
BC_BINOP_MOD_I32,
|
||||||
|
BC_BINOP_SHL_L32,
|
||||||
|
BC_BINOP_SHR_U32,
|
||||||
|
BC_BINOP_SHR_I32,
|
||||||
|
BC_BINOP_CMP_U32,
|
||||||
|
BC_BINOP_CMP_S32
|
||||||
};
|
};
|
||||||
|
|
||||||
class ByteCodeProcedure;
|
class ByteCodeProcedure;
|
||||||
|
@ -171,6 +195,7 @@ public:
|
||||||
int mValue;
|
int mValue;
|
||||||
bool mRelocate, mRegisterFinal;
|
bool mRelocate, mRegisterFinal;
|
||||||
LinkerObject* mLinkerObject;
|
LinkerObject* mLinkerObject;
|
||||||
|
const char* mRuntime;
|
||||||
|
|
||||||
bool IsStore(void) const;
|
bool IsStore(void) const;
|
||||||
bool ChangesAccu(void) const;
|
bool ChangesAccu(void) const;
|
||||||
|
@ -223,6 +248,8 @@ public:
|
||||||
void CalculateOffset(int& total);
|
void CalculateOffset(int& total);
|
||||||
void CopyCode(ByteCodeGenerator* generator, LinkerObject * linkerObject, uint8* target);
|
void CopyCode(ByteCodeGenerator* generator, LinkerObject * linkerObject, uint8* target);
|
||||||
|
|
||||||
|
void LongConstToAccu(int64 val);
|
||||||
|
void LongConstToWork(int64 val);
|
||||||
void IntConstToAccu(int64 val);
|
void IntConstToAccu(int64 val);
|
||||||
void IntConstToAddr(int64 val);
|
void IntConstToAddr(int64 val);
|
||||||
void FloatConstToAccu(double val);
|
void FloatConstToAccu(double val);
|
||||||
|
@ -282,6 +309,7 @@ public:
|
||||||
Linker* mLinker;
|
Linker* mLinker;
|
||||||
|
|
||||||
bool mByteCodeUsed[128];
|
bool mByteCodeUsed[128];
|
||||||
|
LinkerObject* mExtByteCodes[128];
|
||||||
|
|
||||||
void WriteBasicHeader(void);
|
void WriteBasicHeader(void);
|
||||||
void WriteByteCodeHeader(void);
|
void WriteByteCodeHeader(void);
|
||||||
|
|
|
@ -16,7 +16,7 @@ CompilationUnits::CompilationUnits(Errors * errors)
|
||||||
mRuntimeScope = new DeclarationScope(nullptr);
|
mRuntimeScope = new DeclarationScope(nullptr);
|
||||||
mStartup = nullptr;
|
mStartup = nullptr;
|
||||||
|
|
||||||
for (int i = 0; i < 128; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
mByteCodes[i] = nullptr;
|
mByteCodes[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
CompilationUnit* mCompilationUnits, * mPendingUnits;
|
CompilationUnit* mCompilationUnits, * mPendingUnits;
|
||||||
|
|
||||||
Declaration* mStartup;
|
Declaration* mStartup;
|
||||||
Declaration* mByteCodes[128];
|
Declaration* mByteCodes[256];
|
||||||
|
|
||||||
DeclarationScope* mRuntimeScope;
|
DeclarationScope* mRuntimeScope;
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,24 @@ bool Compiler::GenerateCode(void)
|
||||||
RegisterRuntime(loc, Ident::Unique("fcmp"));
|
RegisterRuntime(loc, Ident::Unique("fcmp"));
|
||||||
RegisterRuntime(loc, Ident::Unique("bcexec"));
|
RegisterRuntime(loc, Ident::Unique("bcexec"));
|
||||||
|
|
||||||
//
|
// Register extended byte code functions
|
||||||
|
|
||||||
|
for (int i = 0; i < 128; i++)
|
||||||
|
{
|
||||||
|
Declaration* bcdec = mCompilationUnits->mByteCodes[i + 128];
|
||||||
|
if (bcdec)
|
||||||
|
{
|
||||||
|
LinkerObject* linkerObject = nullptr;
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||||
|
{
|
||||||
|
if (!bcdec->mLinkerObject)
|
||||||
|
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue);
|
||||||
|
mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mErrors->mErrorCount != 0)
|
if (mErrors->mErrorCount != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -483,7 +483,8 @@ bool Declaration::IsNumericType(void) const
|
||||||
return mType == DT_TYPE_INTEGER || mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_ENUM;
|
return mType == DT_TYPE_INTEGER || mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration;
|
Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration;
|
||||||
|
Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration;
|
||||||
|
|
||||||
void InitDeclarations(void)
|
void InitDeclarations(void)
|
||||||
{
|
{
|
||||||
|
@ -504,6 +505,14 @@ void InitDeclarations(void)
|
||||||
TheUnsignedIntTypeDeclaration->mSize = 2;
|
TheUnsignedIntTypeDeclaration->mSize = 2;
|
||||||
TheUnsignedIntTypeDeclaration->mFlags = DTF_DEFINED;
|
TheUnsignedIntTypeDeclaration->mFlags = DTF_DEFINED;
|
||||||
|
|
||||||
|
TheSignedLongTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
||||||
|
TheSignedLongTypeDeclaration->mSize = 4;
|
||||||
|
TheSignedLongTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED;
|
||||||
|
|
||||||
|
TheUnsignedLongTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
||||||
|
TheUnsignedLongTypeDeclaration->mSize = 4;
|
||||||
|
TheUnsignedLongTypeDeclaration->mFlags = DTF_DEFINED;
|
||||||
|
|
||||||
TheSignedCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
TheSignedCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
||||||
TheSignedCharTypeDeclaration->mSize = 1;
|
TheSignedCharTypeDeclaration->mSize = 1;
|
||||||
TheSignedCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED;
|
TheSignedCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED;
|
||||||
|
|
|
@ -174,4 +174,5 @@ public:
|
||||||
|
|
||||||
void InitDeclarations(void);
|
void InitDeclarations(void);
|
||||||
|
|
||||||
extern Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration;
|
extern Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration;
|
||||||
|
extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration;
|
||||||
|
|
|
@ -538,6 +538,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
|
||||||
i += 2;
|
i += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BC_EXTRT:
|
||||||
|
fprintf(file, "EXTRT\t%s, %08x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
|
||||||
|
i += 3;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(file, "\n");
|
fprintf(file, "\n");
|
||||||
|
|
|
@ -251,12 +251,22 @@ static void ConversionConstantFold(InterInstruction * ins, InterInstruction * ci
|
||||||
break;
|
break;
|
||||||
case IA_EXT8TO16S:
|
case IA_EXT8TO16S:
|
||||||
ins->mCode = IC_CONSTANT;
|
ins->mCode = IC_CONSTANT;
|
||||||
ins->mIntValue = (char)(cins->mIntValue);
|
ins->mIntValue = (int8)(cins->mIntValue);
|
||||||
ins->mSTemp[0] = -1;
|
ins->mSTemp[0] = -1;
|
||||||
break;
|
break;
|
||||||
case IA_EXT8TO16U:
|
case IA_EXT8TO16U:
|
||||||
ins->mCode = IC_CONSTANT;
|
ins->mCode = IC_CONSTANT;
|
||||||
ins->mIntValue = (unsigned char)(cins->mIntValue);
|
ins->mIntValue = (uint8)(cins->mIntValue);
|
||||||
|
ins->mSTemp[0] = -1;
|
||||||
|
break;
|
||||||
|
case IA_EXT16TO32S:
|
||||||
|
ins->mCode = IC_CONSTANT;
|
||||||
|
ins->mIntValue = (int16)(cins->mIntValue);
|
||||||
|
ins->mSTemp[0] = -1;
|
||||||
|
break;
|
||||||
|
case IA_EXT16TO32U:
|
||||||
|
ins->mCode = IC_CONSTANT;
|
||||||
|
ins->mIntValue = (uint16)(cins->mIntValue);
|
||||||
ins->mSTemp[0] = -1;
|
ins->mSTemp[0] = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
||||||
stemp = xins->mTTemp;
|
stemp = xins->mTTemp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (v.mType->mSize == 2 && type->mSize == 4)
|
||||||
|
{
|
||||||
|
if (v.mType->mFlags & DTF_SIGNED)
|
||||||
|
{
|
||||||
|
InterInstruction* xins = new InterInstruction();
|
||||||
|
xins->mCode = IC_CONVERSION_OPERATOR;
|
||||||
|
xins->mOperator = IA_EXT16TO32S;
|
||||||
|
xins->mSType[0] = IT_INT16;
|
||||||
|
xins->mSTemp[0] = stemp;
|
||||||
|
xins->mTType = IT_INT32;
|
||||||
|
xins->mTTemp = proc->AddTemporary(IT_INT32);
|
||||||
|
block->Append(xins);
|
||||||
|
stemp = xins->mTTemp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterInstruction* xins = new InterInstruction();
|
||||||
|
xins->mCode = IC_CONVERSION_OPERATOR;
|
||||||
|
xins->mOperator = IA_EXT16TO32U;
|
||||||
|
xins->mSType[0] = IT_INT16;
|
||||||
|
xins->mSTemp[0] = stemp;
|
||||||
|
xins->mTType = IT_INT32;
|
||||||
|
xins->mTTemp = proc->AddTemporary(IT_INT32);
|
||||||
|
block->Append(xins);
|
||||||
|
stemp = xins->mTTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
v.mTemp = stemp;
|
v.mTemp = stemp;
|
||||||
v.mType = type;
|
v.mType = type;
|
||||||
|
@ -507,27 +534,44 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
if (dec->mInteger < -128 || dec->mInteger > 127)
|
if (dec->mInteger < -128 || dec->mInteger > 127)
|
||||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||||
|
ins->mIntValue = int8(dec->mInteger);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dec->mInteger < 0 || dec->mInteger > 255)
|
if (dec->mInteger < 0 || dec->mInteger > 255)
|
||||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||||
|
ins->mIntValue = uint8(dec->mInteger);
|
||||||
}
|
}
|
||||||
ins->mIntValue = char(dec->mInteger);
|
|
||||||
}
|
}
|
||||||
else if (ins->mTType == IT_INT8)
|
else if (ins->mTType == IT_INT16)
|
||||||
{
|
{
|
||||||
if (dec->mFlags & DTF_SIGNED)
|
if (dec->mFlags & DTF_SIGNED)
|
||||||
{
|
{
|
||||||
if (dec->mInteger < -32768 || dec->mInteger > 32767)
|
if (dec->mInteger < -32768 || dec->mInteger > 32767)
|
||||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||||
|
ins->mIntValue = int16(dec->mInteger);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dec->mInteger < 0 || dec->mInteger > 65535)
|
if (dec->mInteger < 0 || dec->mInteger > 65535)
|
||||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||||
|
ins->mIntValue = uint16(dec->mInteger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ins->mTType == IT_INT32)
|
||||||
|
{
|
||||||
|
if (dec->mFlags & DTF_SIGNED)
|
||||||
|
{
|
||||||
|
if (dec->mInteger < -2147483648LL || dec->mInteger > 2147483647LL)
|
||||||
|
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||||
|
ins->mIntValue = int32(dec->mInteger);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dec->mInteger < 0 || dec->mInteger > 4294967296LL)
|
||||||
|
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||||
|
ins->mIntValue = uint32(dec->mInteger);
|
||||||
}
|
}
|
||||||
ins->mIntValue = short(dec->mInteger);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1080,13 +1124,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (vr.mType->mType == DT_TYPE_FLOAT || vl.mType->mType == DT_TYPE_FLOAT)
|
if (vr.mType->mType == DT_TYPE_FLOAT || vl.mType->mType == DT_TYPE_FLOAT)
|
||||||
dtype = TheFloatTypeDeclaration;
|
dtype = TheFloatTypeDeclaration;
|
||||||
else if (vr.mType->mSize < vl.mType->mSize && (vl.mType->mFlags & DTF_SIGNED))
|
else if (vr.mType->mSize < vl.mType->mSize && (vl.mType->mFlags & DTF_SIGNED))
|
||||||
|
{
|
||||||
|
if (vl.mType->mSize == 4)
|
||||||
|
dtype = TheSignedLongTypeDeclaration;
|
||||||
|
else
|
||||||
dtype = TheSignedIntTypeDeclaration;
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
else if (vl.mType->mSize < vr.mType->mSize && (vr.mType->mFlags & DTF_SIGNED))
|
else if (vl.mType->mSize < vr.mType->mSize && (vr.mType->mFlags & DTF_SIGNED))
|
||||||
|
{
|
||||||
|
if (vr.mType->mSize == 4)
|
||||||
|
dtype = TheSignedLongTypeDeclaration;
|
||||||
|
else
|
||||||
dtype = TheSignedIntTypeDeclaration;
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
else if ((vr.mType->mFlags & DTF_SIGNED) && (vl.mType->mFlags & DTF_SIGNED))
|
else if ((vr.mType->mFlags & DTF_SIGNED) && (vl.mType->mFlags & DTF_SIGNED))
|
||||||
|
{
|
||||||
|
if (vl.mType->mSize == 4)
|
||||||
|
dtype = TheSignedLongTypeDeclaration;
|
||||||
|
else
|
||||||
dtype = TheSignedIntTypeDeclaration;
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (vl.mType->mSize == 4 || vr.mType->mSize == 4)
|
||||||
|
dtype = TheUnsignedLongTypeDeclaration;
|
||||||
else
|
else
|
||||||
dtype = TheUnsignedIntTypeDeclaration;
|
dtype = TheUnsignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
vl = CoerceType(proc, block, vl, dtype);
|
vl = CoerceType(proc, block, vl, dtype);
|
||||||
vr = CoerceType(proc, block, vr, dtype);
|
vr = CoerceType(proc, block, vr, dtype);
|
||||||
|
@ -1319,13 +1383,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
else if (vr.mType->mType == DT_TYPE_FLOAT || vl.mType->mType == DT_TYPE_FLOAT)
|
else if (vr.mType->mType == DT_TYPE_FLOAT || vl.mType->mType == DT_TYPE_FLOAT)
|
||||||
dtype = TheFloatTypeDeclaration;
|
dtype = TheFloatTypeDeclaration;
|
||||||
else if (vr.mType->mSize < vl.mType->mSize && (vl.mType->mFlags & DTF_SIGNED))
|
else if (vr.mType->mSize < vl.mType->mSize && (vl.mType->mFlags & DTF_SIGNED))
|
||||||
|
{
|
||||||
|
if (vl.mType->mSize == 4)
|
||||||
|
dtype = TheSignedLongTypeDeclaration;
|
||||||
|
else
|
||||||
dtype = TheSignedIntTypeDeclaration;
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
else if (vl.mType->mSize < vr.mType->mSize && (vr.mType->mFlags & DTF_SIGNED))
|
else if (vl.mType->mSize < vr.mType->mSize && (vr.mType->mFlags & DTF_SIGNED))
|
||||||
|
{
|
||||||
|
if (vr.mType->mSize == 4)
|
||||||
|
dtype = TheSignedLongTypeDeclaration;
|
||||||
|
else
|
||||||
dtype = TheSignedIntTypeDeclaration;
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
else if ((vr.mType->mFlags & DTF_SIGNED) && (vl.mType->mFlags & DTF_SIGNED))
|
else if ((vr.mType->mFlags & DTF_SIGNED) && (vl.mType->mFlags & DTF_SIGNED))
|
||||||
|
{
|
||||||
|
if (vl.mType->mSize == 4)
|
||||||
|
dtype = TheSignedLongTypeDeclaration;
|
||||||
|
else
|
||||||
dtype = TheSignedIntTypeDeclaration;
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (vl.mType->mSize == 4 || vr.mType->mSize == 4)
|
||||||
|
dtype = TheUnsignedLongTypeDeclaration;
|
||||||
else
|
else
|
||||||
dtype = TheUnsignedIntTypeDeclaration;
|
dtype = TheUnsignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
vl = CoerceType(proc, block, vl, dtype);
|
vl = CoerceType(proc, block, vl, dtype);
|
||||||
vr = CoerceType(proc, block, vr, dtype);
|
vr = CoerceType(proc, block, vr, dtype);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,10 +8,20 @@ class NativeCodeProcedure;
|
||||||
class NativeCodeBasicBlock;
|
class NativeCodeBasicBlock;
|
||||||
class NativeCodeGenerator;
|
class NativeCodeGenerator;
|
||||||
|
|
||||||
|
enum NativeRegisterDataMode
|
||||||
|
{
|
||||||
|
NRDM_UNKNOWN,
|
||||||
|
NRDM_IMMEDIATE,
|
||||||
|
NRDM_IMMEDIATE_ADDRESS,
|
||||||
|
NRDM_ZERO_PAGE
|
||||||
|
};
|
||||||
|
|
||||||
struct NativeRegisterData
|
struct NativeRegisterData
|
||||||
{
|
{
|
||||||
bool mImmediate, mZeroPage;
|
NativeRegisterDataMode mMode;
|
||||||
int mValue;
|
int mValue;
|
||||||
|
uint32 mFlags;
|
||||||
|
LinkerObject * mLinkerObject;
|
||||||
|
|
||||||
NativeRegisterData(void);
|
NativeRegisterData(void);
|
||||||
|
|
||||||
|
|
|
@ -897,6 +897,39 @@ Expression* Parser::ParseSimpleExpression(void)
|
||||||
exp->mDecValue = dec;
|
exp->mDecValue = dec;
|
||||||
exp->mDecType = dec->mBase;
|
exp->mDecType = dec->mBase;
|
||||||
|
|
||||||
|
mScanner->NextToken();
|
||||||
|
break;
|
||||||
|
case TK_INTEGERU:
|
||||||
|
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
dec->mInteger = mScanner->mTokenInteger;
|
||||||
|
dec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
exp->mDecValue = dec;
|
||||||
|
exp->mDecType = dec->mBase;
|
||||||
|
|
||||||
|
mScanner->NextToken();
|
||||||
|
break;
|
||||||
|
case TK_INTEGERL:
|
||||||
|
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
dec->mInteger = mScanner->mTokenInteger;
|
||||||
|
if (dec->mInteger < 0x80000000)
|
||||||
|
dec->mBase = TheSignedLongTypeDeclaration;
|
||||||
|
else
|
||||||
|
dec->mBase = TheUnsignedLongTypeDeclaration;
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
exp->mDecValue = dec;
|
||||||
|
exp->mDecType = dec->mBase;
|
||||||
|
|
||||||
|
mScanner->NextToken();
|
||||||
|
break;
|
||||||
|
case TK_INTEGERUL:
|
||||||
|
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
dec->mInteger = mScanner->mTokenInteger;
|
||||||
|
dec->mBase = TheUnsignedLongTypeDeclaration;
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
exp->mDecValue = dec;
|
||||||
|
exp->mDecType = dec->mBase;
|
||||||
|
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
break;
|
break;
|
||||||
case TK_NUMBER:
|
case TK_NUMBER:
|
||||||
|
@ -1819,6 +1852,16 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
|
||||||
exp->mDecValue = dec;
|
exp->mDecValue = dec;
|
||||||
exp->mDecType = dec->mBase;
|
exp->mDecType = dec->mBase;
|
||||||
|
|
||||||
|
mScanner->NextToken();
|
||||||
|
break;
|
||||||
|
case TK_INTEGERU:
|
||||||
|
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
dec->mInteger = mScanner->mTokenInteger;
|
||||||
|
dec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
exp->mDecValue = dec;
|
||||||
|
exp->mDecType = dec->mBase;
|
||||||
|
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2459,7 +2502,7 @@ void Parser::ParsePragma(void)
|
||||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER && exp->mDecValue->mInteger >= 0 && exp->mDecValue->mInteger < 128)
|
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER && exp->mDecValue->mInteger >= 0 && exp->mDecValue->mInteger < 256)
|
||||||
{
|
{
|
||||||
if (mCompilationUnits->mByteCodes[exp->mDecValue->mInteger])
|
if (mCompilationUnits->mByteCodes[exp->mDecValue->mInteger])
|
||||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate bytecode function");
|
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate bytecode function");
|
||||||
|
|
|
@ -32,6 +32,9 @@ const char* TokenNames[] = {
|
||||||
"'long'",
|
"'long'",
|
||||||
"'continue'",
|
"'continue'",
|
||||||
"'integer'",
|
"'integer'",
|
||||||
|
"'integeru'",
|
||||||
|
"'integerl'",
|
||||||
|
"'integerul'",
|
||||||
"'bool'",
|
"'bool'",
|
||||||
"'const'",
|
"'const'",
|
||||||
"'volatile'",
|
"'volatile'",
|
||||||
|
@ -1037,7 +1040,13 @@ void Scanner::NextRawToken(void)
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
mErrors->Error(mLocation, EERR_SYNTAX, "Missing digits in hex constant");
|
mErrors->Error(mLocation, EERR_SYNTAX, "Missing digits in hex constant");
|
||||||
|
|
||||||
mToken = TK_INTEGER;
|
if (mTokenChar == 'L' || mTokenChar == 'l')
|
||||||
|
{
|
||||||
|
NextChar();
|
||||||
|
mToken = TK_INTEGERUL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mToken = TK_INTEGERU;
|
||||||
mTokenInteger = mant;
|
mTokenInteger = mant;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1288,7 +1297,7 @@ void Scanner::CharToken(void)
|
||||||
|
|
||||||
if (mLine[mOffset] && mLine[mOffset] == '\'')
|
if (mLine[mOffset] && mLine[mOffset] == '\'')
|
||||||
{
|
{
|
||||||
mToken = TK_INTEGER;
|
mToken = TK_INTEGERU;
|
||||||
mOffset++;
|
mOffset++;
|
||||||
NextChar();
|
NextChar();
|
||||||
}
|
}
|
||||||
|
@ -1358,7 +1367,14 @@ void Scanner::ParseNumberToken(void)
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
Error("Missing digits in hex constant");
|
Error("Missing digits in hex constant");
|
||||||
|
|
||||||
mToken = TK_INTEGER;
|
if (mTokenChar == 'L' || mTokenChar == 'l')
|
||||||
|
{
|
||||||
|
NextChar();
|
||||||
|
mToken = TK_INTEGERUL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mToken = TK_INTEGERU;
|
||||||
|
|
||||||
mTokenInteger = mant;
|
mTokenInteger = mant;
|
||||||
}
|
}
|
||||||
else if (mant == 0 && (mTokenChar == 'b' || mTokenChar == 'B'))
|
else if (mant == 0 && (mTokenChar == 'b' || mTokenChar == 'B'))
|
||||||
|
@ -1376,7 +1392,13 @@ void Scanner::ParseNumberToken(void)
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
Error("Missing digits in binary constant");
|
Error("Missing digits in binary constant");
|
||||||
|
|
||||||
mToken = TK_INTEGER;
|
if (mTokenChar == 'L' || mTokenChar == 'l')
|
||||||
|
{
|
||||||
|
NextChar();
|
||||||
|
mToken = TK_INTEGERUL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mToken = TK_INTEGERU;
|
||||||
mTokenInteger = mant;
|
mTokenInteger = mant;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1397,7 +1419,27 @@ void Scanner::ParseNumberToken(void)
|
||||||
|
|
||||||
if (mTokenChar != '.')
|
if (mTokenChar != '.')
|
||||||
{
|
{
|
||||||
|
if (mTokenChar == 'U' || mTokenChar == 'u')
|
||||||
|
{
|
||||||
|
NextChar();
|
||||||
|
if (mTokenChar == 'L' || mTokenChar == 'l')
|
||||||
|
{
|
||||||
|
NextChar();
|
||||||
|
mToken = TK_INTEGERUL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mToken = TK_INTEGERU;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mTokenChar == 'L' || mTokenChar == 'l')
|
||||||
|
{
|
||||||
|
NextChar();
|
||||||
|
mToken = TK_INTEGERL;
|
||||||
|
}
|
||||||
|
else
|
||||||
mToken = TK_INTEGER;
|
mToken = TK_INTEGER;
|
||||||
|
}
|
||||||
mTokenInteger = mant;
|
mTokenInteger = mant;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1461,6 +1503,9 @@ int64 Scanner::PrepParseSimple(void)
|
||||||
switch (mToken)
|
switch (mToken)
|
||||||
{
|
{
|
||||||
case TK_INTEGER:
|
case TK_INTEGER:
|
||||||
|
case TK_INTEGERU:
|
||||||
|
case TK_INTEGERL:
|
||||||
|
case TK_INTEGERUL:
|
||||||
v = mTokenInteger;
|
v = mTokenInteger;
|
||||||
NextToken();
|
NextToken();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -31,6 +31,9 @@ enum Token
|
||||||
TK_LONG,
|
TK_LONG,
|
||||||
TK_CONTINUE,
|
TK_CONTINUE,
|
||||||
TK_INTEGER,
|
TK_INTEGER,
|
||||||
|
TK_INTEGERU,
|
||||||
|
TK_INTEGERL,
|
||||||
|
TK_INTEGERUL,
|
||||||
TK_BOOL,
|
TK_BOOL,
|
||||||
TK_CONST,
|
TK_CONST,
|
||||||
TK_VOLATILE,
|
TK_VOLATILE,
|
||||||
|
|
Loading…
Reference in New Issue