mirror of
https://github.com/irmen/prog8.git
synced 2025-02-10 14:32:20 +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
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
...
|
||||
|
@ -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)
|
||||
|
@ -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"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user