mirror of
https://github.com/irmen/prog8.git
synced 2025-02-25 20:29:04 +00:00
ir: EXT and EXTS opcodes now have 2 registers to avoid type clash
This commit is contained in:
parent
e6b158bc97
commit
5037033fcf
@ -167,15 +167,18 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
} else false
|
} else false
|
||||||
if (assignment.value is PtMachineRegister) {
|
if (assignment.value is PtMachineRegister) {
|
||||||
valueRegister = (assignment.value as PtMachineRegister).register
|
valueRegister = (assignment.value as PtMachineRegister).register
|
||||||
if(extendByteToWord)
|
if(extendByteToWord) {
|
||||||
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister), null)
|
valueRegister = codeGen.registers.nextFree()
|
||||||
|
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister, reg2=(assignment.value as PtMachineRegister).register), null)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val tr = expressionEval.translateExpression(assignment.value)
|
val tr = expressionEval.translateExpression(assignment.value)
|
||||||
valueRegister = tr.resultReg
|
valueRegister = tr.resultReg
|
||||||
addToResult(result, tr, valueRegister, -1)
|
addToResult(result, tr, valueRegister, -1)
|
||||||
if(extendByteToWord) {
|
if(extendByteToWord) {
|
||||||
|
valueRegister = codeGen.registers.nextFree()
|
||||||
val opcode = if(assignment.value.type in SignedDatatypes) Opcode.EXTS else Opcode.EXT
|
val opcode = if(assignment.value.type in SignedDatatypes) Opcode.EXTS else Opcode.EXT
|
||||||
addInstr(result, IRInstruction(opcode, IRDataType.BYTE, reg1 = valueRegister), null)
|
addInstr(result, IRInstruction(opcode, IRDataType.BYTE, reg1=valueRegister, reg2=tr.resultReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,10 +172,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val compareReg = codeGen.registers.nextFree()
|
val compareReg = codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=tr.resultReg)
|
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=tr.resultReg)
|
||||||
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, immediate = 0x80)
|
it += IRInstruction(Opcode.BSTPOS, labelSymbol = notNegativeLabel)
|
||||||
it += IRInstruction(Opcode.BEQ, IRDataType.BYTE, reg1=compareReg, immediate = 0, labelSymbol = notNegativeLabel)
|
|
||||||
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=tr.resultReg)
|
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=tr.resultReg)
|
||||||
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=tr.resultReg)
|
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(notNegativeLabel, null)
|
result += IRCodeChunk(notNegativeLabel, null)
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||||
@ -185,8 +183,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val compareReg = codeGen.registers.nextFree()
|
val compareReg = codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=tr.resultReg)
|
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=tr.resultReg)
|
||||||
it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, immediate = 0x8000)
|
it += IRInstruction(Opcode.BSTPOS, labelSymbol = notNegativeLabel)
|
||||||
it += IRInstruction(Opcode.BEQ, IRDataType.WORD, reg1=compareReg, immediate = 0, labelSymbol = notNegativeLabel)
|
|
||||||
it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=tr.resultReg)
|
it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=tr.resultReg)
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(notNegativeLabel, null)
|
result += IRCodeChunk(notNegativeLabel, null)
|
||||||
|
@ -274,13 +274,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
when(cast.value.type) {
|
when(cast.value.type) {
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
// byte -> uword: sign extend
|
// byte -> uword: sign extend
|
||||||
actualResultReg2 = tr.resultReg
|
actualResultReg2 = codeGen.registers.nextFree()
|
||||||
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2), null)
|
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2 = tr.resultReg), null)
|
||||||
}
|
}
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
// ubyte -> uword: sign extend
|
// ubyte -> uword: sign extend
|
||||||
actualResultReg2 = tr.resultReg
|
actualResultReg2 = codeGen.registers.nextFree()
|
||||||
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2), null)
|
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2 = tr.resultReg), null)
|
||||||
}
|
}
|
||||||
DataType.WORD -> {
|
DataType.WORD -> {
|
||||||
actualResultReg2 = tr.resultReg
|
actualResultReg2 = tr.resultReg
|
||||||
@ -296,13 +296,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
when(cast.value.type) {
|
when(cast.value.type) {
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
// byte -> word: sign extend
|
// byte -> word: sign extend
|
||||||
actualResultReg2 = tr.resultReg
|
actualResultReg2 = codeGen.registers.nextFree()
|
||||||
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2), null)
|
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2=tr.resultReg), null)
|
||||||
}
|
}
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
// byte -> word: sign extend
|
// byte -> word: sign extend
|
||||||
actualResultReg2 = tr.resultReg
|
actualResultReg2 = codeGen.registers.nextFree()
|
||||||
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2), null)
|
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2=tr.resultReg), null)
|
||||||
}
|
}
|
||||||
DataType.UWORD -> {
|
DataType.UWORD -> {
|
||||||
actualResultReg2 = tr.resultReg
|
actualResultReg2 = tr.resultReg
|
||||||
|
@ -2,7 +2,7 @@ TODO
|
|||||||
====
|
====
|
||||||
|
|
||||||
- fix VM print_w
|
- fix VM print_w
|
||||||
- fix VM abs(byte) it always returns 0
|
- fix VM abs(byte) it always returns 0 also check abs(word)
|
||||||
- IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register.
|
- IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register.
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -3,28 +3,13 @@
|
|||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
sub set_color(ubyte dummy, uword arg) {
|
||||||
|
arg++
|
||||||
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte @shared current = cx16.screen_mode(0, true)
|
ubyte intens
|
||||||
ubyte @shared width
|
set_color(0, (intens >> 1) * $111)
|
||||||
ubyte @shared height
|
|
||||||
txt.print_ub(current)
|
|
||||||
txt.nl()
|
|
||||||
cx16.set_screen_mode(128)
|
|
||||||
%asm {{
|
|
||||||
phx
|
|
||||||
jsr cx16.get_screen_mode
|
|
||||||
sta p8_current
|
|
||||||
stx p8_width
|
|
||||||
sty p8_height
|
|
||||||
plx
|
|
||||||
}}
|
|
||||||
txt.print_ub(current)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_ub(width)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_ub(height)
|
|
||||||
txt.nl()
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
byte intensity = -25
|
byte intensity = -25
|
||||||
txt.print_b(intensity)
|
txt.print_b(intensity)
|
||||||
|
@ -115,8 +115,8 @@ ARITHMETIC
|
|||||||
----------
|
----------
|
||||||
All have type b or w or f. Note: result types are the same as operand types! E.g. byte*byte->byte.
|
All have type b or w or f. Note: result types are the same as operand types! E.g. byte*byte->byte.
|
||||||
|
|
||||||
exts reg1 - reg1 = signed extension of reg1 (byte to word, or word to long) (note: unlike M68k, exts.b -> word and exts.w -> long. The latter is not yet implemented yet as we don't have longs yet)
|
exts reg1, reg2 - reg1 = signed extension of reg2 (byte to word, or word to long) (note: unlike M68k, exts.b -> word and exts.w -> long. The latter is not yet implemented yet as we don't have longs yet)
|
||||||
ext reg1 - reg1 = unsigned extension of reg1 (which in practice just means clearing the MSB / MSW) (note: unlike M68k, ext.b -> word and ext.w -> long. The latter is not yet implemented yet as we don't have longs yet)
|
ext reg1, reg2 - reg1 = unsigned extension of reg2 (which in practice just means clearing the MSB / MSW) (note: unlike M68k, ext.b -> word and ext.w -> long. The latter is not yet implemented yet as we don't have longs yet)
|
||||||
inc reg1 - reg1 = reg1+1
|
inc reg1 - reg1 = reg1+1
|
||||||
incm address - memory at address += 1
|
incm address - memory at address += 1
|
||||||
dec reg1 - reg1 = reg1-1
|
dec reg1 - reg1 = reg1-1
|
||||||
@ -583,8 +583,8 @@ val instructionFormats = mutableMapOf(
|
|||||||
Opcode.DIVMODR to InstructionFormat.from("BW,<>r1,<r2"),
|
Opcode.DIVMODR to InstructionFormat.from("BW,<>r1,<r2"),
|
||||||
Opcode.DIVMOD to InstructionFormat.from("BW,<>r1,<i"),
|
Opcode.DIVMOD to InstructionFormat.from("BW,<>r1,<i"),
|
||||||
Opcode.CMP to InstructionFormat.from("BW,<r1,<r2"),
|
Opcode.CMP to InstructionFormat.from("BW,<r1,<r2"),
|
||||||
Opcode.EXT to InstructionFormat.from("BW,<>r1"),
|
Opcode.EXT to InstructionFormat.from("BW,>r1,<r2"),
|
||||||
Opcode.EXTS to InstructionFormat.from("BW,<>r1"),
|
Opcode.EXTS to InstructionFormat.from("BW,>r1,<r2"),
|
||||||
Opcode.ANDR to InstructionFormat.from("BW,<>r1,<r2"),
|
Opcode.ANDR to InstructionFormat.from("BW,<>r1,<r2"),
|
||||||
Opcode.AND to InstructionFormat.from("BW,<>r1,<i"),
|
Opcode.AND to InstructionFormat.from("BW,<>r1,<i"),
|
||||||
Opcode.ANDM to InstructionFormat.from("BW,<r1,<>a"),
|
Opcode.ANDM to InstructionFormat.from("BW,<r1,<>a"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user