aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-06 18:24:47 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-06 18:24:47 +0100
commitdf888d6cce6a31e55eac4e21ccd496ce6023dfeb (patch)
treec8c62f9307aa737c8d2289449422e4e31314b916 /src/main/java
parent163460c063814f659713ceed417e5f0be4a800d0 (diff)
Add int-equals instruction
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java37
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenTypes.java1
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java29
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmConditionCode.java5
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmIcmp.java14
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmInstruction.java2
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmZext.java13
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java3
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmI32Eq.java4
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java2
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java3
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java3
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java2
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/IntEqualsInstruction.java10
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 {
+}