@@ -463,10 +463,6 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
463463
464464 private fun translateRegularAssign (assignment : PtAssignment ): IRCodeChunks {
465465 // note: assigning array and string values is done via an explicit memcopy/stringcopy function call.
466- val targetIdent = assignment.target.identifier
467- val targetMemory = assignment.target.memory
468- val targetArray = assignment.target.array
469- val targetPointerDeref = assignment.target.pointerDeref
470466 val valueDt = irType(assignment.value.type)
471467 val targetDt = irType(assignment.target.type)
472468 val result = mutableListOf<IRCodeChunkBase >()
@@ -507,98 +503,107 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
507503 }
508504 }
509505
510- if (targetIdent!= null ) {
511- val instruction = if (zero) {
512- IRInstruction (Opcode .STOREZM , targetDt, labelSymbol = targetIdent.name)
513- } else {
514- if (targetDt == IRDataType .FLOAT ) {
515- require(valueFpRegister>= 0 )
516- IRInstruction (Opcode .STOREM , targetDt, fpReg1 = valueFpRegister, labelSymbol = targetIdent.name)
517- }
518- else {
519- require(valueRegister>= 0 )
520- IRInstruction (Opcode .STOREM , targetDt, reg1 = valueRegister, labelSymbol = targetIdent.name)
521- }
522- }
523- result + = IRCodeChunk (null , null ).also { it + = instruction }
524- return result
525- }
526- else if (targetArray!= null ) {
527- val eltSize = codeGen.program.memsizer.memorySize(targetArray.type, null )
528- val variable = targetArray.variable
529- if (variable== null )
530- translateRegularAssignPointerIndexed(result, targetArray.pointerderef!! , eltSize, targetArray, zero, targetDt, valueRegister, valueFpRegister)
531- else if (variable.type.isPointer)
532- assignToIndexedSimplePointer(result, variable, eltSize, targetArray, zero, targetDt, valueRegister, valueFpRegister)
533- else
534- translateRegularAssignArrayIndexed(result, variable.name, eltSize, targetArray, zero, targetDt, valueRegister, valueFpRegister)
535- return result
536- }
537- else if (targetMemory!= null ) {
538- require(targetDt == IRDataType .BYTE ) { " must be byte type ${targetMemory.position} " }
539- if (zero) {
540- if (targetMemory.address is PtNumber ) {
541- val chunk = IRCodeChunk (null , null ).also { it + = IRInstruction (Opcode .STOREZM , targetDt, address = (targetMemory.address as PtNumber ).number.toInt()) }
542- result + = chunk
543- } else {
544- val tr = expressionEval.translateExpression(targetMemory.address)
545- val addressReg = tr.resultReg
546- addToResult(result, tr, tr.resultReg, - 1 )
547- result + = IRCodeChunk (null , null ).also {
548- it + = IRInstruction (Opcode .STOREZI , targetDt, reg1= addressReg)
506+ with (assignment.target) {
507+ when {
508+ identifier != null -> {
509+ val instruction = if (zero) {
510+ IRInstruction (Opcode .STOREZM , targetDt, labelSymbol = identifier!! .name)
511+ } else {
512+ if (targetDt == IRDataType .FLOAT ) {
513+ require(valueFpRegister>= 0 )
514+ IRInstruction (Opcode .STOREM , targetDt, fpReg1 = valueFpRegister, labelSymbol = identifier!! .name)
515+ }
516+ else {
517+ require(valueRegister>= 0 )
518+ IRInstruction (Opcode .STOREM , targetDt, reg1 = valueRegister, labelSymbol = identifier!! .name)
519+ }
549520 }
550- }
551- } else {
552- val constAddress = targetMemory.address as ? PtNumber
553- if (constAddress!= null ) {
554- addInstr(result, IRInstruction (Opcode .STOREM , targetDt, reg1= valueRegister, address= constAddress.number.toInt()), null )
521+ result + = IRCodeChunk (null , null ).also { it + = instruction }
555522 return result
556523 }
557- val ptrWithOffset = targetMemory.address as ? PtBinaryExpression
558- if (ptrWithOffset!= null ) {
559- if (ptrWithOffset.operator == " +" && ptrWithOffset.left is PtIdentifier ) {
560- val constOffset = (ptrWithOffset.right as ? PtNumber )?.number?.toInt()
561- if (constOffset in 0 .. 255 ) {
562- val ptrName = (ptrWithOffset.left as PtIdentifier ).name
563- val pointerReg = codeGen.registers.next(IRDataType .WORD )
524+ memory != null -> {
525+ require(targetDt == IRDataType .BYTE ) { " must be byte type ${memory!! .position} " }
526+ if (zero) {
527+ if (memory!! .address is PtNumber ) {
528+ val chunk = IRCodeChunk (null , null ).also { it + = IRInstruction (Opcode .STOREZM , targetDt, address = (memory!! .address as PtNumber ).number.toInt()) }
529+ result + = chunk
530+ } else {
531+ val tr = expressionEval.translateExpression(memory!! .address)
532+ val addressReg = tr.resultReg
533+ addToResult(result, tr, tr.resultReg, - 1 )
564534 result + = IRCodeChunk (null , null ).also {
565- it + = IRInstruction (Opcode .LOADM , IRDataType .WORD , reg1= pointerReg, labelSymbol = ptrName)
566- it + = IRInstruction (Opcode .STOREFIELD , IRDataType .BYTE , reg1= valueRegister, reg2= pointerReg, immediate = constOffset)
535+ it + = IRInstruction (Opcode .STOREZI , targetDt, reg1= addressReg)
567536 }
537+ }
538+ } else {
539+ val constAddress = memory!! .address as ? PtNumber
540+ if (constAddress!= null ) {
541+ addInstr(result, IRInstruction (Opcode .STOREM , targetDt, reg1= valueRegister, address= constAddress.number.toInt()), null )
568542 return result
569543 }
570- }
571- val offsetTypecast = ptrWithOffset.right as ? PtTypeCast
572- if (ptrWithOffset.operator == " +" && ptrWithOffset.left is PtIdentifier && (ptrWithOffset.right.type.isByte || offsetTypecast?.value?.type?.isByte== true )) {
573- // STOREIX only works with byte index.
574- val tr = if (offsetTypecast?.value?.type?.isByte== true )
575- expressionEval.translateExpression(offsetTypecast.value)
576- else
577- expressionEval.translateExpression(ptrWithOffset.right)
544+ val ptrWithOffset = memory!! .address as ? PtBinaryExpression
545+ if (ptrWithOffset!= null ) {
546+ if (ptrWithOffset.operator == " +" && ptrWithOffset.left is PtIdentifier ) {
547+ val constOffset = (ptrWithOffset.right as ? PtNumber )?.number?.toInt()
548+ if (constOffset in 0 .. 255 ) {
549+ val ptrName = (ptrWithOffset.left as PtIdentifier ).name
550+ val pointerReg = codeGen.registers.next(IRDataType .WORD )
551+ result + = IRCodeChunk (null , null ).also {
552+ it + = IRInstruction (Opcode .LOADM , IRDataType .WORD , reg1= pointerReg, labelSymbol = ptrName)
553+ it + = IRInstruction (Opcode .STOREFIELD , IRDataType .BYTE , reg1= valueRegister, reg2= pointerReg, immediate = constOffset)
554+ }
555+ return result
556+ }
557+ }
558+ val offsetTypecast = ptrWithOffset.right as ? PtTypeCast
559+ if (ptrWithOffset.operator == " +" && ptrWithOffset.left is PtIdentifier && (ptrWithOffset.right.type.isByte || offsetTypecast?.value?.type?.isByte== true )) {
560+ // STOREIX only works with byte index.
561+ val tr = if (offsetTypecast?.value?.type?.isByte== true )
562+ expressionEval.translateExpression(offsetTypecast.value)
563+ else
564+ expressionEval.translateExpression(ptrWithOffset.right)
565+ addToResult(result, tr, tr.resultReg, - 1 )
566+ val ptrName = (ptrWithOffset.left as PtIdentifier ).name
567+ addInstr(result, IRInstruction (Opcode .STOREIX , IRDataType .BYTE , reg1= valueRegister, reg2= tr.resultReg, labelSymbol = ptrName), null )
568+ return result
569+ }
570+ }
571+
572+ val tr = expressionEval.translateExpression(memory!! .address)
573+ val addressReg = tr.resultReg
578574 addToResult(result, tr, tr.resultReg, - 1 )
579- val ptrName = (ptrWithOffset.left as PtIdentifier ).name
580- addInstr(result, IRInstruction (Opcode .STOREIX , IRDataType .BYTE , reg1= valueRegister, reg2= tr.resultReg, labelSymbol = ptrName), null )
575+ addInstr(result, IRInstruction (Opcode .STOREI , targetDt, reg1= valueRegister, reg2= addressReg), null )
581576 return result
582577 }
578+
579+ return result
583580 }
581+ array != null -> {
582+ val eltSize = codeGen.program.memsizer.memorySize(array!! .type, null )
583+ val variable = array!! .variable
584+ if (variable== null )
585+ translateRegularAssignPointerIndexed(result, array!! .pointerderef!! , eltSize, array!! , zero, targetDt, valueRegister, valueFpRegister)
586+ else if (variable.type.isPointer)
587+ assignToIndexedSimplePointer(result, variable, eltSize, array!! , zero, targetDt, valueRegister, valueFpRegister)
588+ else
589+ translateRegularAssignArrayIndexed(result, variable.name, eltSize, array!! , zero, targetDt, valueRegister, valueFpRegister)
590+ return result
591+ }
592+ pointerDeref != null -> {
593+ val (addressReg, offset) = codeGen.evaluatePointerAddressIntoReg(result, pointerDeref!! )
594+ val actualValueReg = if (pointerDeref!! .type.isFloat) valueFpRegister else valueRegister
595+ codeGen.storeValueAtPointersLocation(result, addressReg, offset, pointerDeref!! .type, zero, actualValueReg)
596+ return result
584597
585- val tr = expressionEval.translateExpression(targetMemory.address)
586- val addressReg = tr.resultReg
587- addToResult(result, tr, tr.resultReg, - 1 )
588- addInstr(result, IRInstruction (Opcode .STOREI , targetDt, reg1= valueRegister, reg2= addressReg), null )
589- return result
598+ }
599+ indexedPointerDeref != null -> {
600+ TODO (" assign to indexed pointer ${assignment.target.position} - for now, split up the assignment target using a temporary pointer variable" )
601+ }
602+ else -> {
603+ throw AssemblyError (" weird assigntarget" )
604+ }
590605 }
591-
592- return result
593606 }
594- else if (targetPointerDeref!= null ) {
595- val (addressReg, offset) = codeGen.evaluatePointerAddressIntoReg(result, targetPointerDeref)
596- val actualValueReg = if (targetPointerDeref.type.isFloat) valueFpRegister else valueRegister
597- codeGen.storeValueAtPointersLocation(result, addressReg, offset, targetPointerDeref.type, zero, actualValueReg)
598- return result
599- }
600- else
601- throw AssemblyError (" weird assigntarget" )
602607 }
603608
604609 private fun assignToIndexedSimplePointer (
0 commit comments