diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-06 18:24:47 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-06 18:24:47 +0100 |
| commit | df888d6cce6a31e55eac4e21ccd496ce6023dfeb (patch) | |
| tree | c8c62f9307aa737c8d2289449422e4e31314b916 /src/main/java | |
| parent | 163460c063814f659713ceed417e5f0be4a800d0 (diff) | |
Add int-equals instruction
Diffstat (limited to 'src/main/java')
14 files changed, 125 insertions, 3 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java index 135e9552..8b2520e7 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java @@ -5,7 +5,10 @@ import org.shedlang.compiler.backends.llvm.ir.ast.LlvmFunctionDeclaration; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmGlobalDefinition; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmModule; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmParam; +import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmConditionCode; +import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmIcmp; import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmReturn; +import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmZext; import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand; import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperandInt; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypes; @@ -153,6 +156,40 @@ public class LlvmCodeGen { yield context.push(fieldValue); } + case IntEqualsInstruction intEquals -> { + var rightResult = context.pop(); + var right = rightResult.value(); + context = rightResult.context(); + + var leftResult = context.pop(); + var left = leftResult.value(); + context = leftResult.context(); + + var targetI1Result = context.generateVariableLocal(LlvmCodeGenLocalVariableSpace.TEMPORARY); + var targetI1 = targetI1Result.value(); + context = targetI1Result.context(); + + var targetResult = context.generateVariableLocal(LlvmCodeGenLocalVariableSpace.TEMPORARY); + var target = targetResult.value(); + context = targetResult.context(); + + yield context + .addInstruction(new LlvmIcmp( + targetI1, + LlvmConditionCode.EQ, + LlvmCodeGenTypes.INT_TYPE, + left, + right + )) + .addInstruction(new LlvmZext( + target, + LlvmTypes.INT_1, + targetI1, + LlvmCodeGenTypes.VALUE_TYPE + )) + .push(target); + } + case LocalLoadInstruction localLoad -> context.push(context.shedLocal(localLoad.name())); diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenTypes.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenTypes.java index d8c18bed..a8367384 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenTypes.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenTypes.java @@ -8,4 +8,5 @@ public class LlvmCodeGenTypes { } public static final LlvmTypeScalar VALUE_TYPE = LlvmTypes.INT_64; + public static final LlvmTypeScalar INT_TYPE = LlvmTypes.INT_64; } diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java index 716deb8a..cad69bc0 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java @@ -30,6 +30,15 @@ public class LlvmIrSerializer { writer.append("\n"); } + private static void serializeConditionCode( + LlvmConditionCode conditionCode, + Appendable writer + ) throws IOException { + writer.append(switch (conditionCode) { + case EQ -> "eq"; + }); + } + public static void serializeInstruction(LlvmInstruction instruction, Appendable writer) throws IOException { switch (instruction) { case LlvmAdd add -> { @@ -69,6 +78,17 @@ public class LlvmIrSerializer { serializeTypedOperand(index, writer); } } + case LlvmIcmp icmp -> { + serializeVariable(icmp.target(), writer); + writer.append(" = icmp "); + serializeConditionCode(icmp.conditionCode(), writer); + writer.append(" "); + serializeType(icmp.type(), writer); + writer.append(" "); + serializeOperand(icmp.left(), writer); + writer.append(", "); + serializeOperand(icmp.right(), writer); + } case LlvmIntToPtr intToPtr -> { serializeVariable(intToPtr.target(), writer); writer.append(" = inttoptr "); @@ -99,6 +119,15 @@ public class LlvmIrSerializer { writer.append(", ptr "); serializeOperand(store.pointer(), writer); } + case LlvmZext zext -> { + serializeVariable(zext.target(), writer); + writer.append(" = zext "); + serializeType(zext.sourceType(), writer); + writer.append(" "); + serializeOperand(zext.value(), writer); + writer.append(" to "); + serializeType(zext.targetType(), writer); + } } } diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmConditionCode.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmConditionCode.java new file mode 100644 index 00000000..4dcc331e --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmConditionCode.java @@ -0,0 +1,5 @@ +package org.shedlang.compiler.backends.llvm.ir.ast.instructions; + +public enum LlvmConditionCode { + EQ, +} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmIcmp.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmIcmp.java new file mode 100644 index 00000000..01e23385 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmIcmp.java @@ -0,0 +1,14 @@ +package org.shedlang.compiler.backends.llvm.ir.ast.instructions; + +import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand; +import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariable; +import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; + +public record LlvmIcmp( + LlvmVariable target, + LlvmConditionCode conditionCode, + LlvmType type, + LlvmOperand left, + LlvmOperand right +) implements LlvmInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmInstruction.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmInstruction.java index fda542d4..a9073029 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmInstruction.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmInstruction.java @@ -1,4 +1,4 @@ package org.shedlang.compiler.backends.llvm.ir.ast.instructions; -public sealed interface LlvmInstruction permits LlvmAdd, LlvmCall, LlvmGetElementPtr, LlvmIntToPtr, LlvmLoad, LlvmPtrToInt, LlvmStore { +public sealed interface LlvmInstruction permits LlvmAdd, LlvmCall, LlvmGetElementPtr, LlvmIcmp, LlvmIntToPtr, LlvmLoad, LlvmPtrToInt, LlvmStore, LlvmZext { } diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmZext.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmZext.java new file mode 100644 index 00000000..7268b5e7 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmZext.java @@ -0,0 +1,13 @@ +package org.shedlang.compiler.backends.llvm.ir.ast.instructions; + +import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand; +import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariable; +import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; + +public record LlvmZext( + LlvmVariable target, + LlvmType sourceType, + LlvmOperand value, + LlvmType targetType +) implements LlvmInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java index 212c81ff..77887f94 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java @@ -179,6 +179,9 @@ public class WasmCodeGen { ); } + case IntEqualsInstruction intEqualsInstruction -> + context.addInstruction(new WasmI32Eq()); + case LocalLoadInstruction localLoad -> context.addInstruction(new WasmLocalGet(context.shedLocal(localLoad.name()))); diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmI32Eq.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmI32Eq.java new file mode 100644 index 00000000..5f384d53 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmI32Eq.java @@ -0,0 +1,4 @@ +package org.shedlang.compiler.backends.wasm.structure.ast.instructions; + +public record WasmI32Eq() implements WasmInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java index 0e802d51..2e4b166c 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java @@ -1,4 +1,4 @@ package org.shedlang.compiler.backends.wasm.structure.ast.instructions; -public sealed interface WasmInstruction permits WasmCall, WasmCallIndirect, WasmDrop, WasmGlobalGet, WasmGlobalSet, WasmI32Const, WasmI32Load, WasmI32Store, WasmI64Const, WasmIf, WasmLocalGet, WasmLocalSet, WasmMemoryAddressConst, WasmMemoryGrow, WasmReturn, WasmTableElementIndexConst { +public sealed interface WasmInstruction permits WasmCall, WasmCallIndirect, WasmDrop, WasmGlobalGet, WasmGlobalSet, WasmI32Const, WasmI32Eq, WasmI32Load, WasmI32Store, WasmI64Const, WasmIf, WasmLocalGet, WasmLocalSet, WasmMemoryAddressConst, WasmMemoryGrow, WasmReturn, WasmTableElementIndexConst { } diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java index c9552a96..549c5004 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java @@ -104,6 +104,9 @@ public class WasmBinaryFormatInstructions { writer.writeByte(0x42); writer.writeSignedInt64(i64Const.value()); } + case WasmI32Eq i32Eq -> { + writer.writeByte(0x46); + } // == Relocatable Instructions == diff --git a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java b/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java index ef832b90..ac58103c 100644 --- a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java +++ b/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java @@ -81,6 +81,9 @@ public class InstructionSerializer { treeString(fieldLoad.namespaceName().toString()), treeString(fieldLoad.fieldName()) ); + + case IntEqualsInstruction intEquals -> + treeList(treeIdentifier("int-equals")); case LocalLoadInstruction localLoadInstruction -> treeList( diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java index 6a21404c..f3c8a30a 100644 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java +++ b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.stackir.instructions; import org.shedlang.compiler.sources.Source; public sealed interface Instruction - permits CallInstruction, DefineFunctionInstruction, DiscardInstruction, FieldLoadInstruction, LocalLoadInstruction, LocalStoreInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ReturnInstruction { + permits CallInstruction, DefineFunctionInstruction, DiscardInstruction, FieldLoadInstruction, IntEqualsInstruction, LocalLoadInstruction, LocalStoreInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ReturnInstruction { Source source(); } diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/IntEqualsInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/IntEqualsInstruction.java new file mode 100644 index 00000000..623db1c4 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/stackir/instructions/IntEqualsInstruction.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.stackir.instructions; + +import org.shedlang.compiler.sources.Source; + +/** + * Pop two values from the stack, compare them as Ints, and push a Bool onto + * the stack: true if equal, false if not equal. + */ +public record IntEqualsInstruction(Source source) implements Instruction { +} |
