mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-20 02:32:36 +00:00
Working on fixing casts.
This commit is contained in:
parent
17a0db4472
commit
71cedd4d29
8
src/main/fragment/_deref_pduc1=vduz1.asm
Normal file
8
src/main/fragment/_deref_pduc1=vduz1.asm
Normal file
@ -0,0 +1,8 @@
|
||||
lda {z1}
|
||||
sta {c1}
|
||||
lda {z1}+1
|
||||
sta {c1}+1
|
||||
lda {z1}+2
|
||||
sta {c1}+2
|
||||
lda {z1}+3
|
||||
sta {c1}+3
|
4
src/main/fragment/pbuz1=_ptr_vwuz2.asm
Normal file
4
src/main/fragment/pbuz1=_ptr_vwuz2.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
sta {z1}+1
|
@ -0,0 +1,7 @@
|
||||
lda {c1},x
|
||||
sec
|
||||
sbc {z1}
|
||||
sta {c1},x
|
||||
lda {c1}+1,x
|
||||
sbc {z1}+1
|
||||
sta {c1}+1,x
|
@ -0,0 +1,7 @@
|
||||
lda {c1},y
|
||||
sec
|
||||
sbc {z1}
|
||||
sta {c1},y
|
||||
lda {c1}+1,y
|
||||
sbc {z1}+1
|
||||
sta {c1}+1,y
|
3
src/main/fragment/vbsaa=_neg__sbyte_vbuaa.asm
Normal file
3
src/main/fragment/vbsaa=_neg__sbyte_vbuaa.asm
Normal file
@ -0,0 +1,3 @@
|
||||
eor #$ff
|
||||
clc
|
||||
adc #$01
|
3
src/main/fragment/vwsz1=_sword_vbuaa.asm
Normal file
3
src/main/fragment/vwsz1=_sword_vbuaa.asm
Normal file
@ -0,0 +1,3 @@
|
||||
sta {z1}
|
||||
lda #0
|
||||
sta {z1}+1
|
@ -270,7 +270,7 @@ public class Compiler {
|
||||
optimizations.add(new Pass2SizeOfSimplification(program));
|
||||
optimizations.add(new Pass2InlineDerefIdx(program));
|
||||
optimizations.add(new Pass2DeInlineWordDerefIdx(program));
|
||||
optimizations.add(new Pass2ConstantCastSimplification(program));
|
||||
optimizations.add(new PassNCastSimplification(program));
|
||||
pass2Execute(optimizations);
|
||||
}
|
||||
|
||||
@ -312,7 +312,7 @@ public class Compiler {
|
||||
constantOptimizations.add(new Pass2ConstantValues(program));
|
||||
constantOptimizations.add(new Pass2ConstantAdditionElimination(program));
|
||||
constantOptimizations.add(new Pass2ConstantSimplification(program));
|
||||
constantOptimizations.add(new Pass2ConstantCastSimplification(program));
|
||||
constantOptimizations.add(new PassNCastSimplification(program));
|
||||
constantOptimizations.add(new Pass2ConstantIfs(program));
|
||||
pass2Execute(constantOptimizations);
|
||||
|
||||
@ -373,6 +373,8 @@ public class Compiler {
|
||||
new Pass3AssertConstants(program).check();
|
||||
new Pass3AssertArrayLengths(program).check();
|
||||
new Pass3AssertNoMulDivMod(program).check();
|
||||
new Pass3AddAssignmentCasts(program).execute();
|
||||
new PassNCastSimplification(program).execute();
|
||||
new PassNBlockSequencePlanner(program).step();
|
||||
// Phi lifting ensures that all variables in phi-blocks are in different live range equivalence classes
|
||||
new Pass3PhiLifting(program).perform();
|
||||
|
@ -5,6 +5,8 @@ import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.Registers;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.OperatorUnary;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
@ -228,13 +230,15 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
if(value instanceof CastValue) {
|
||||
CastValue castVal = (CastValue) value;
|
||||
SymbolType toType = castVal.getToType();
|
||||
value = castVal.getValue();
|
||||
return bind(value, toType);
|
||||
OperatorUnary castUnary = Operators.getCastUnary(toType);
|
||||
return getOperatorFragmentName(castUnary) + bind(castVal.getValue());
|
||||
} else if(value instanceof ConstantCastValue) {
|
||||
ConstantCastValue castVal = (ConstantCastValue) value;
|
||||
SymbolType toType = castVal.getToType();
|
||||
value = castVal.getValue();
|
||||
return bind(value, toType);
|
||||
if(castType==null) {
|
||||
return bind(castVal.getValue(), castVal.getToType());
|
||||
} else {
|
||||
return bind(castVal.getValue(), castType);
|
||||
}
|
||||
} else if(value instanceof PointerDereference) {
|
||||
PointerDereference deref = (PointerDereference) value;
|
||||
SymbolType ptrType = null;
|
||||
|
@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.VariableIntermediate;
|
||||
@ -331,4 +332,55 @@ public interface ProgramExpressionBinary extends ProgramExpression {
|
||||
}
|
||||
|
||||
|
||||
/** Assignment of a phi value to a phi variable. */
|
||||
class ProgramExpressionBinaryPhiValueAssignemnt implements ProgramExpressionBinary {
|
||||
|
||||
private final StatementPhiBlock.PhiVariable phiVariable;
|
||||
private final StatementPhiBlock.PhiRValue value;
|
||||
|
||||
public ProgramExpressionBinaryPhiValueAssignemnt(StatementPhiBlock.PhiVariable phiVariable, StatementPhiBlock.PhiRValue value) {
|
||||
this.phiVariable = phiVariable;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue getLeft() {
|
||||
return phiVariable.getVariable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperatorBinary getOperator() {
|
||||
return Operators.ASSIGNMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue getRight() {
|
||||
return value.getrValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
|
||||
throw new InternalError("Not supported!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
|
||||
if(getRight() instanceof ConstantValue) {
|
||||
value.setrValue(new ConstantCastValue(toType, (ConstantValue) getRight()));
|
||||
} else {
|
||||
// Try to use CastValue - may later have to be supported!
|
||||
value.setrValue(new CastValue(toType, getRight()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Value value) {
|
||||
throw new InternalError("Not supported!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.ListIterator;
|
||||
@ -32,6 +33,8 @@ public class ProgramExpressionIterator {
|
||||
} else if(programValue.get() instanceof PointerDereferenceIndexed) {
|
||||
handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed(programValue), null, null, null);
|
||||
} else if(programValue.get() instanceof ConstantCastValue) {
|
||||
handler.execute(new ProgramExpressionUnary.ProgramExpressionUnaryConstantCast(programValue), null, null, null);
|
||||
} else if(programValue.get() instanceof CastValue) {
|
||||
handler.execute(new ProgramExpressionUnary.ProgramExpressionUnaryCast(programValue), null, null, null);
|
||||
}
|
||||
};
|
||||
@ -55,6 +58,12 @@ public class ProgramExpressionIterator {
|
||||
if(condJump.getrValue1() != null && condJump.getOperator() != null && condJump.getrValue2() != null) {
|
||||
handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryConditionalJump(condJump), stmt, stmtIt, block);
|
||||
}
|
||||
} else if(stmt instanceof StatementPhiBlock) {
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) stmt).getPhiVariables()) {
|
||||
for(StatementPhiBlock.PhiRValue value : phiVariable.getValues()) {
|
||||
handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryPhiValueAssignemnt(phiVariable, value), stmt, stmtIt, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Iterate all statement values
|
||||
ProgramValueIterator.execute(stmt, programValueHandler, stmtIt, block);
|
||||
|
@ -3,10 +3,7 @@ package dk.camelot64.kickc.model.iterator;
|
||||
import dk.camelot64.kickc.model.operators.OperatorUnary;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.values.ConstantCastValue;
|
||||
import dk.camelot64.kickc.model.values.ConstantUnary;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.Value;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
/**
|
||||
* A binary expression in the program being iterated by {@link ProgramExpressionIterator}
|
||||
@ -84,12 +81,12 @@ public interface ProgramExpressionUnary extends ProgramExpression {
|
||||
}
|
||||
|
||||
/** Unary cast expression {@link ConstantCastValue} as part of a constant expression. */
|
||||
class ProgramExpressionUnaryCast implements ProgramExpressionUnary {
|
||||
class ProgramExpressionUnaryConstantCast implements ProgramExpressionUnary {
|
||||
|
||||
/** A ProgramValue containing a {@link ConstantCastValue}. */
|
||||
private ProgramValue programValue;
|
||||
|
||||
ProgramExpressionUnaryCast(ProgramValue programValue) {
|
||||
ProgramExpressionUnaryConstantCast(ProgramValue programValue) {
|
||||
this.programValue = programValue;
|
||||
}
|
||||
|
||||
@ -114,6 +111,36 @@ public interface ProgramExpressionUnary extends ProgramExpression {
|
||||
|
||||
}
|
||||
|
||||
/** Unary cast expression {@link CastValue} as part of a constant expression. */
|
||||
class ProgramExpressionUnaryCast implements ProgramExpressionUnary {
|
||||
|
||||
/** A ProgramValue containing a {@link CastValue}. */
|
||||
private ProgramValue programValue;
|
||||
|
||||
ProgramExpressionUnaryCast(ProgramValue programValue) {
|
||||
this.programValue = programValue;
|
||||
}
|
||||
|
||||
public CastValue getConstantUnary() {
|
||||
return (CastValue) programValue.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperatorUnary getOperator() {
|
||||
return Operators.getCastUnary(getConstantUnary().getToType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue getOperand() {
|
||||
return getConstantUnary().getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Value value) {
|
||||
programValue.set(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class OperatorSizeOf extends OperatorUnary {
|
||||
if(typeSizeConstant == null) {
|
||||
// Constant not found - create it
|
||||
long typeSize = type.getSizeBytes();
|
||||
typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize));
|
||||
typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize&0xff, SymbolType.BYTE));
|
||||
programScope.add(typeSizeConstant);
|
||||
}
|
||||
return typeSizeConstant.getRef();
|
||||
|
@ -175,4 +175,23 @@ public class SymbolTypeConversion {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the left side of an assignment needs a cast to be assigned to the right side
|
||||
* @param lValueType The type of the LValue
|
||||
* @param rValueType The type of the RValue
|
||||
* @return true if the left side needs a cast
|
||||
*/
|
||||
public static boolean assignmentCastNeeded(SymbolType lValueType, SymbolType rValueType) {
|
||||
if(lValueType.equals(rValueType))
|
||||
return false;
|
||||
else if(lValueType instanceof SymbolTypePointer && rValueType instanceof SymbolTypePointer)
|
||||
return false;
|
||||
else if(lValueType instanceof SymbolTypePointer && SymbolType.STRING.equals(rValueType))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Add casts to assignments where the lvalue and rvalue have different matching types.
|
||||
*/
|
||||
public class Pass3AddAssignmentCasts extends Pass2SsaOptimization {
|
||||
|
||||
public Pass3AddAssignmentCasts(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
AtomicBoolean modified = new AtomicBoolean(false);
|
||||
ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programExpression instanceof ProgramExpressionBinary) {
|
||||
if(Operators.ASSIGNMENT.equals(programExpression.getOperator())) {
|
||||
ProgramExpressionBinary binary = (ProgramExpressionBinary) programExpression;
|
||||
SymbolType leftType = SymbolTypeInference.inferType(getScope(), binary.getLeft());
|
||||
SymbolType rightType = SymbolTypeInference.inferType(getScope(), binary.getRight());
|
||||
if(SymbolTypeConversion.assignmentTypeMatch(leftType, rightType) && SymbolTypeConversion.assignmentCastNeeded(leftType, rightType)) {
|
||||
binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getScope());
|
||||
getLog().append("Adding assignment cast to " + currentStmt.toString(getProgram(), false));
|
||||
modified.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return modified.get();
|
||||
}
|
||||
}
|
@ -3,19 +3,21 @@ package dk.camelot64.kickc.passes;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.operators.OperatorCast;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeIntegerFixed;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.model.types.*;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantPointer;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/** Simplifies casts of (number) constants to a type. */
|
||||
public class Pass2ConstantCastSimplification extends Pass2SsaOptimization {
|
||||
/** Simplifies casts
|
||||
* - Inlines casts of (number) constants
|
||||
* - Removes unnecessary casts
|
||||
* */
|
||||
public class PassNCastSimplification extends Pass2SsaOptimization {
|
||||
|
||||
public Pass2ConstantCastSimplification(Program program) {
|
||||
public PassNCastSimplification(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@ -27,8 +29,15 @@ public class Pass2ConstantCastSimplification extends Pass2SsaOptimization {
|
||||
OperatorCast operatorCast = (OperatorCast) programExpression.getOperator();
|
||||
ProgramExpressionUnary unary = (ProgramExpressionUnary) programExpression;
|
||||
SymbolType castType = operatorCast.getToType();
|
||||
if(unary.getOperand() instanceof ConstantInteger) {
|
||||
ConstantInteger constantInteger = (ConstantInteger) unary.getOperand();
|
||||
SymbolType operandType = SymbolTypeInference.inferType(getScope(), ((ProgramExpressionUnary) programExpression).getOperand());
|
||||
RValue unaryOperand = unary.getOperand();
|
||||
if(!SymbolTypeConversion.assignmentCastNeeded(castType, operandType)) {
|
||||
// Cast Not needed
|
||||
programExpression.set(unaryOperand);
|
||||
getLog().append("Simplifying constant integer cast " + unaryOperand.toString(getProgram()));
|
||||
optimized.set(true);
|
||||
} else if(unaryOperand instanceof ConstantInteger) {
|
||||
ConstantInteger constantInteger = (ConstantInteger) unaryOperand;
|
||||
if(SymbolType.NUMBER.equals(constantInteger.getType())) {
|
||||
if(castType instanceof SymbolTypeIntegerFixed ) {
|
||||
ConstantInteger newConstInt = new ConstantInteger(constantInteger.getInteger(), castType);
|
@ -32,14 +32,52 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Avaiting String concatenation
|
||||
|
||||
@Test
|
||||
public void testLiterals() throws IOException, URISyntaxException {
|
||||
compileAndCompare("literals");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConstantStringConcat() throws IOException, URISyntaxException {
|
||||
compileAndCompare("constant-string-concat");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatChar() throws IOException, URISyntaxException {
|
||||
compileAndCompare("concat-char");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testC64DtvGfxModes() throws IOException, URISyntaxException {
|
||||
compileAndCompare("c64dtv-gfxmodes", 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testC64DtvGfxExplorer() throws IOException, URISyntaxException {
|
||||
compileAndCompare("c64dtv-gfxexplorer", 10);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testFragmentVariations() throws IOException, URISyntaxException {
|
||||
compileAndCompare("fragment-variations");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeInference() throws IOException, URISyntaxException {
|
||||
compileAndCompare("type-inference", log().verboseSSAOptimize());
|
||||
compileAndCompare("type-inference");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMixedArray1() throws IOException, URISyntaxException {
|
||||
compileAndCompare("mixed-array-1", log());
|
||||
compileAndCompare("mixed-array-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1059,11 +1097,6 @@ public class TestPrograms {
|
||||
compileAndCompare("assignment-chained");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatChar() throws IOException, URISyntaxException {
|
||||
compileAndCompare("concat-char");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstMultDiv() throws IOException, URISyntaxException {
|
||||
compileAndCompare("const-mult-div");
|
||||
@ -1184,11 +1217,6 @@ public class TestPrograms {
|
||||
compileAndCompare("c64dtv-8bppcharstretch");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testC64DtvGfxExplorer() throws IOException, URISyntaxException {
|
||||
compileAndCompare("c64dtv-gfxexplorer", 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInlineString2() throws IOException, URISyntaxException {
|
||||
compileAndCompare("inline-string-2");
|
||||
@ -1209,11 +1237,6 @@ public class TestPrograms {
|
||||
compileAndCompare("keyboard-glitch");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testC64DtvGfxModes() throws IOException, URISyntaxException {
|
||||
compileAndCompare("c64dtv-gfxmodes", 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoromCharset() throws IOException, URISyntaxException {
|
||||
compileAndCompare("norom-charset");
|
||||
@ -1359,11 +1382,6 @@ public class TestPrograms {
|
||||
compileAndCompare("arrays-init");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstantStringConcat() throws IOException, URISyntaxException {
|
||||
compileAndCompare("constant-string-concat");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrueInlineWords() throws IOException, URISyntaxException {
|
||||
compileAndCompare("true-inline-words");
|
||||
@ -1579,10 +1597,6 @@ public class TestPrograms {
|
||||
compileAndCompare("halfscii");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLiterals() throws IOException, URISyntaxException {
|
||||
compileAndCompare("literals");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScroll() throws IOException, URISyntaxException {
|
||||
|
16
src/test/kc/fragment-variations.kc
Normal file
16
src/test/kc/fragment-variations.kc
Normal file
@ -0,0 +1,16 @@
|
||||
// Tests that ASM fragment variations works
|
||||
// ASM fragment variations "cast" constants to different types
|
||||
|
||||
void main() {
|
||||
dword* screen = 0x400;
|
||||
word w = 10;
|
||||
screen[0] = mul16u(w, w);
|
||||
w = 1000;
|
||||
screen[1] = mul16u(w, w);
|
||||
}
|
||||
|
||||
dword mul16u(word b, word a) {
|
||||
dword mb = b;
|
||||
return mb+a;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ void main() {
|
||||
byte[] bc = { 1, 2, 3, 4 };
|
||||
// Strings
|
||||
byte[] sa = "camelot";
|
||||
byte[] sb = "cml"+" "+"rules";
|
||||
//byte[] sb = { 'a', 'b', 'c', 0};
|
||||
|
||||
SCREEN[idx++] = '0'+sizeof(0);
|
||||
SCREEN[idx++] = '0'+sizeof(idx);
|
||||
@ -37,6 +37,6 @@ void main() {
|
||||
SCREEN[idx++] = '0'+sizeof(bb);
|
||||
SCREEN[idx++] = '0'+sizeof(bc);
|
||||
SCREEN[idx++] = '0'+sizeof(sa);
|
||||
SCREEN[idx++] = '0'+sizeof(sb);
|
||||
//SCREEN[idx++] = '0'+sizeof(sb);
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user