ir: EXT and EXTS opcodes now have 2 registers to avoid type clash

This commit is contained in:
Irmen de Jong 2023-07-08 22:42:11 +02:00
parent e6b158bc97
commit 5037033fcf
6 changed files with 27 additions and 42 deletions

View File

@ -167,15 +167,18 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
} else false
if (assignment.value is PtMachineRegister) {
valueRegister = (assignment.value as PtMachineRegister).register
if(extendByteToWord)
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister), null)
if(extendByteToWord) {
valueRegister = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister, reg2=(assignment.value as PtMachineRegister).register), null)
}
} else {
val tr = expressionEval.translateExpression(assignment.value)
valueRegister = tr.resultReg
addToResult(result, tr, valueRegister, -1)
if(extendByteToWord) {
valueRegister = codeGen.registers.nextFree()
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)
}
}
}

View File

@ -172,10 +172,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val compareReg = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=tr.resultReg)
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, immediate = 0x80)
it += IRInstruction(Opcode.BEQ, IRDataType.BYTE, reg1=compareReg, immediate = 0, labelSymbol = notNegativeLabel)
it += IRInstruction(Opcode.BSTPOS, labelSymbol = notNegativeLabel)
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=tr.resultReg)
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=tr.resultReg)
}
result += IRCodeChunk(notNegativeLabel, null)
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()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=tr.resultReg)
it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, immediate = 0x8000)
it += IRInstruction(Opcode.BEQ, IRDataType.WORD, reg1=compareReg, immediate = 0, labelSymbol = notNegativeLabel)
it += IRInstruction(Opcode.BSTPOS, labelSymbol = notNegativeLabel)
it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=tr.resultReg)
}
result += IRCodeChunk(notNegativeLabel, null)

View File

@ -274,13 +274,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
when(cast.value.type) {
DataType.BYTE -> {
// byte -> uword: sign extend
actualResultReg2 = tr.resultReg
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2), null)
actualResultReg2 = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2 = tr.resultReg), null)
}
DataType.UBYTE -> {
// ubyte -> uword: sign extend
actualResultReg2 = tr.resultReg
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2), null)
actualResultReg2 = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2 = tr.resultReg), null)
}
DataType.WORD -> {
actualResultReg2 = tr.resultReg
@ -296,13 +296,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
when(cast.value.type) {
DataType.BYTE -> {
// byte -> word: sign extend
actualResultReg2 = tr.resultReg
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2), null)
actualResultReg2 = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2=tr.resultReg), null)
}
DataType.UBYTE -> {
// byte -> word: sign extend
actualResultReg2 = tr.resultReg
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2), null)
actualResultReg2 = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2=tr.resultReg), null)
}
DataType.UWORD -> {
actualResultReg2 = tr.resultReg

View File

@ -2,7 +2,7 @@ TODO
====
- 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.
...

View File

@ -3,28 +3,13 @@
%option no_sysinit
main {
sub set_color(ubyte dummy, uword arg) {
arg++
}
sub start() {
ubyte @shared current = cx16.screen_mode(0, true)
ubyte @shared width
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()
ubyte intens
set_color(0, (intens >> 1) * $111)
byte intensity = -25
txt.print_b(intensity)

View File

@ -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.
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)
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)
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, 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
incm address - memory at address += 1
dec reg1 - reg1 = reg1-1
@ -583,8 +583,8 @@ val instructionFormats = mutableMapOf(
Opcode.DIVMODR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.DIVMOD to InstructionFormat.from("BW,<>r1,<i"),
Opcode.CMP to InstructionFormat.from("BW,<r1,<r2"),
Opcode.EXT to InstructionFormat.from("BW,<>r1"),
Opcode.EXTS to InstructionFormat.from("BW,<>r1"),
Opcode.EXT to InstructionFormat.from("BW,>r1,<r2"),
Opcode.EXTS to InstructionFormat.from("BW,>r1,<r2"),
Opcode.ANDR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.AND to InstructionFormat.from("BW,<>r1,<i"),
Opcode.ANDM to InstructionFormat.from("BW,<r1,<>a"),