aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-07 18:01:28 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-07 18:01:28 +0100
commit69ce0b822262c9ea5ae9cc4e89be0fa4498eaf25 (patch)
treefacd2ed40e3f4a001eee045bc809d57121b33b81 /src
parentdf888d6cce6a31e55eac4e21ccd496ce6023dfeb (diff)
Add int-ne instruction
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java75
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java1
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/instructions/LlvmConditionCode.java1
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java5
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmI32Ne.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.java5
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java2
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/IntNotEqualInstruction.java10
-rw-r--r--src/test/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenIntNotEqualTests.java28
-rw-r--r--src/test/java/org/shedlang/compiler/backends/wasm/WasmCodeGenIntNotEqualTests.java24
-rw-r--r--src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java12
-rw-r--r--src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java12
14 files changed, 142 insertions, 42 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 8b2520e7..389067b9 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
@@ -156,39 +156,11 @@ 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 IntEqualsInstruction intEquals ->
+ generateBinaryComparison(LlvmConditionCode.EQ, context);
+
+ case IntNotEqualInstruction intNotEqual ->
+ generateBinaryComparison(LlvmConditionCode.NE, context);
case LocalLoadInstruction localLoad ->
context.push(context.shedLocal(localLoad.name()));
@@ -253,4 +225,41 @@ public class LlvmCodeGen {
}
};
}
+
+ private static LlvmCodeGenContext generateBinaryComparison(
+ LlvmConditionCode conditionCode,
+ LlvmCodeGenContext context
+ ) {
+ 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();
+
+ return context
+ .addInstruction(new LlvmIcmp(
+ targetI1,
+ conditionCode,
+ LlvmCodeGenTypes.INT_TYPE,
+ left,
+ right
+ ))
+ .addInstruction(new LlvmZext(
+ target,
+ LlvmTypes.INT_1,
+ targetI1,
+ LlvmCodeGenTypes.VALUE_TYPE
+ ))
+ .push(target);
+ }
}
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 cad69bc0..9985d244 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
@@ -36,6 +36,7 @@ public class LlvmIrSerializer {
) throws IOException {
writer.append(switch (conditionCode) {
case EQ -> "eq";
+ case NE -> "ne";
});
}
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
index 4dcc331e..3566926b 100644
--- 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
@@ -2,4 +2,5 @@ package org.shedlang.compiler.backends.llvm.ir.ast.instructions;
public enum LlvmConditionCode {
EQ,
+ NE,
}
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 77887f94..d3d99bbc 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
@@ -179,9 +179,12 @@ public class WasmCodeGen {
);
}
- case IntEqualsInstruction intEqualsInstruction ->
+ case IntEqualsInstruction intEquals ->
context.addInstruction(new WasmI32Eq());
+ case IntNotEqualInstruction intNotEqual ->
+ context.addInstruction(new WasmI32Ne());
+
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/WasmI32Ne.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmI32Ne.java
new file mode 100644
index 00000000..a76bddd3
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmI32Ne.java
@@ -0,0 +1,4 @@
+package org.shedlang.compiler.backends.wasm.structure.ast.instructions;
+
+public record WasmI32Ne() 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 2e4b166c..2286536a 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, WasmI32Eq, WasmI32Load, WasmI32Store, WasmI64Const, WasmIf, WasmLocalGet, WasmLocalSet, WasmMemoryAddressConst, WasmMemoryGrow, WasmReturn, WasmTableElementIndexConst {
+public sealed interface WasmInstruction permits WasmCall, WasmCallIndirect, WasmDrop, WasmGlobalGet, WasmGlobalSet, WasmI32Const, WasmI32Eq, WasmI32Load, WasmI32Ne, 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 549c5004..ea162fbd 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
@@ -107,6 +107,9 @@ public class WasmBinaryFormatInstructions {
case WasmI32Eq i32Eq -> {
writer.writeByte(0x46);
}
+ case WasmI32Ne i32Ne -> {
+ writer.writeByte(0x47);
+ }
// == 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 ac58103c..00757988 100644
--- a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java
+++ b/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java
@@ -83,7 +83,10 @@ public class InstructionSerializer {
);
case IntEqualsInstruction intEquals ->
- treeList(treeIdentifier("int-equals"));
+ treeList(treeIdentifier("int-eq"));
+
+ case IntNotEqualInstruction intNotEqual ->
+ treeList(treeIdentifier("int-ne"));
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 f3c8a30a..5d4bd139 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, IntEqualsInstruction, LocalLoadInstruction, LocalStoreInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ReturnInstruction {
+ permits CallInstruction, DefineFunctionInstruction, DiscardInstruction, FieldLoadInstruction, IntEqualsInstruction, IntNotEqualInstruction, LocalLoadInstruction, LocalStoreInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ReturnInstruction {
Source source();
}
diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/IntNotEqualInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/IntNotEqualInstruction.java
new file mode 100644
index 00000000..722723d2
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/stackir/instructions/IntNotEqualInstruction.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 not equal, false if equal.
+ */
+public record IntNotEqualInstruction(Source source) implements Instruction {
+}
diff --git a/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenIntNotEqualTests.java b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenIntNotEqualTests.java
new file mode 100644
index 00000000..b5759f61
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenIntNotEqualTests.java
@@ -0,0 +1,28 @@
+package org.shedlang.compiler.backends.llvm;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.shedlang.compiler.backends.llvm.ir.ast.LlvmIr;
+import org.shedlang.compiler.stackir.instructions.Instructions;
+import org.shedlang.compiler.testing.snapshots.SnapshotResolver;
+import org.shedlang.compiler.testing.snapshots.Snapshotter;
+
+import java.io.IOException;
+
+import static org.shedlang.compiler.backends.llvm.LlvmCodeGenTesting.serializeContext;
+
+@ExtendWith({SnapshotResolver.class})
+public class LlvmCodeGenIntNotEqualTests {
+ @Test
+ public void intNotEqualIsCompiledToComparison(Snapshotter snapshotter) throws IOException {
+ var instruction = Instructions.intNotEqual();
+ var context = LlvmCodeGenContext.EMPTY
+ .push(LlvmIr.variableLocal("a"))
+ .push(LlvmIr.variableLocal("b"))
+ .push(LlvmIr.variableLocal("c"));
+
+ var result = LlvmCodeGen.generateInstruction(instruction, context);
+
+ snapshotter.assertSnapshot(serializeContext(result));
+ }
+}
diff --git a/src/test/java/org/shedlang/compiler/backends/wasm/WasmCodeGenIntNotEqualTests.java b/src/test/java/org/shedlang/compiler/backends/wasm/WasmCodeGenIntNotEqualTests.java
new file mode 100644
index 00000000..dc924eb9
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/backends/wasm/WasmCodeGenIntNotEqualTests.java
@@ -0,0 +1,24 @@
+package org.shedlang.compiler.backends.wasm;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.shedlang.compiler.stackir.instructions.Instructions;
+import org.shedlang.compiler.testing.snapshots.SnapshotResolver;
+import org.shedlang.compiler.testing.snapshots.Snapshotter;
+
+import java.io.IOException;
+
+import static org.shedlang.compiler.backends.wasm.WasmCodeGenTesting.objdumpContext;
+
+@ExtendWith({SnapshotResolver.class})
+public class WasmCodeGenIntNotEqualTests {
+ @Test
+ public void intNotEqualIsCompiledToI32Ne(Snapshotter snapshotter) throws IOException, InterruptedException {
+ var instruction = Instructions.intNotEqual();
+ var context = WasmCodeGenContext.EMPTY;
+
+ var result = WasmCodeGen.generateInstruction(instruction, context);
+
+ snapshotter.assertSnapshot(objdumpContext(result));
+ }
+}
diff --git a/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java b/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java
index 10588ec1..a2d5065a 100644
--- a/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java
+++ b/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java
@@ -74,13 +74,23 @@ public class InstructionSerializerTests {
assertThat(string, equalTo("(field-load \"Example/Lib\" \"x\")"));
}
+
@Test
public void canSerializeIntEquals() {
var instruction = Instructions.intEquals();
var string = serialize(instruction);
- assertThat(string, equalTo("(int-equals)"));
+ assertThat(string, equalTo("(int-eq)"));
+ }
+
+ @Test
+ public void canSerializeIntNotEqual() {
+ var instruction = Instructions.intNotEqual();
+
+ var string = serialize(instruction);
+
+ assertThat(string, equalTo("(int-ne)"));
}
@Test
diff --git a/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java b/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java
index a1630727..2b198617 100644
--- a/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java
+++ b/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java
@@ -22,6 +22,14 @@ public class Instructions {
return new FieldLoadInstruction(namespaceName, fieldName, Sources.NULL);
}
+ public static Instruction intEquals() {
+ return new IntEqualsInstruction(Sources.NULL);
+ }
+
+ public static Instruction intNotEqual() {
+ return new IntNotEqualInstruction(Sources.NULL);
+ }
+
public static Instruction localLoad(String name) {
return new LocalLoadInstruction(name, Sources.NULL);
}
@@ -61,8 +69,4 @@ public class Instructions {
public static Instruction return_() {
return new ReturnInstruction(Sources.NULL);
}
-
- public static Instruction intEquals() {
- return new IntEqualsInstruction(Sources.NULL);
- }
}