summaryrefslogtreecommitdiff
path: root/rts/Interpreter.c
diff options
context:
space:
mode:
authorLuite Stegeman <stegeman@gmail.com>2023-01-03 12:06:48 +0900
committerLuite Stegeman <stegeman@gmail.com>2023-01-06 18:16:24 +0900
commit28f8c0ebbfe623784988745af75dcf3fdbdd3ca5 (patch)
treea9461a0de296bdd2dbe6cba66db866235ce2cba9 /rts/Interpreter.c
parentb2a2db04b24a4654261db8e0db6ad7bac1b3d7cf (diff)
downloadhaskell-28f8c0ebbfe623784988745af75dcf3fdbdd3ca5.tar.gz
Add support for sized literals in the bytecode interpreter.
The bytecode interpreter only has branching instructions for word-sized values. These are used for pattern matching. Branching instructions for other types (e.g. Int16# or Word8#) weren't needed, since unoptimized Core or STG never requires branching on types like this. It's now possible for optimized STG to reach the bytecode generator (e.g. fat interface files or certain compiler flag combinations), which requires dealing with various sized literals in branches. This patch improves support for generating bytecode from optimized STG by adding the following new bytecode instructions: TESTLT_I64 TESTEQ_I64 TESTLT_I32 TESTEQ_I32 TESTLT_I16 TESTEQ_I16 TESTLT_I8 TESTEQ_I8 TESTLT_W64 TESTEQ_W64 TESTLT_W32 TESTEQ_W32 TESTLT_W16 TESTEQ_W16 TESTLT_W8 TESTEQ_W8 Fixes #21945
Diffstat (limited to 'rts/Interpreter.c')
-rw-r--r--rts/Interpreter.c174
1 files changed, 172 insertions, 2 deletions
diff --git a/rts/Interpreter.c b/rts/Interpreter.c
index 00aced17f9..1108ca8ed0 100644
--- a/rts/Interpreter.c
+++ b/rts/Interpreter.c
@@ -75,6 +75,8 @@
#define BCO_PTR(n) (W_)ptrs[n]
#define BCO_LIT(n) literals[n]
+#define BCO_LITW64(n) (*(StgWord64*)(literals+n))
+#define BCO_LITI64(n) (*(StgInt64*)(literals+n))
#define LOAD_STACK_POINTERS \
Sp = cap->r.rCurrentTSO->stackobj->sp; \
@@ -1728,6 +1730,46 @@ run_BCO:
goto nextInsn;
}
+ case bci_TESTLT_I64: {
+ // There should be an Int64 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgInt64 stackInt = (*(StgInt64*)Sp_plusW(1));
+ if (stackInt >= BCO_LITI64(discr))
+ bciPtr = failto;
+ goto nextInsn;
+ }
+
+ case bci_TESTLT_I32: {
+ // There should be an Int32 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgInt32 stackInt = (*(StgInt32*)Sp_plusW(1));
+ if (stackInt >= (StgInt32)BCO_LIT(discr))
+ bciPtr = failto;
+ goto nextInsn;
+ }
+
+ case bci_TESTLT_I16: {
+ // There should be an Int16 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgInt16 stackInt = (*(StgInt16*)Sp_plusW(1));
+ if (stackInt >= (StgInt16)BCO_LIT(discr))
+ bciPtr = failto;
+ goto nextInsn;
+ }
+
+ case bci_TESTLT_I8: {
+ // There should be an Int8 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgInt8 stackInt = (*(StgInt8*)Sp_plusW(1));
+ if (stackInt >= (StgInt8)BCO_LIT(discr))
+ bciPtr = failto;
+ goto nextInsn;
+ }
+
case bci_TESTEQ_I: {
// There should be an Int at SpW(1), and an info table at SpW(0).
int discr = BCO_GET_LARGE_ARG;
@@ -1739,8 +1781,52 @@ run_BCO:
goto nextInsn;
}
+ case bci_TESTEQ_I64: {
+ // There should be an Int64 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgInt64 stackInt = (*(StgInt64*)Sp_plusW(1));
+ if (stackInt != BCO_LITI64(discr)) {
+ bciPtr = failto;
+ }
+ goto nextInsn;
+ }
+
+ case bci_TESTEQ_I32: {
+ // There should be an Int32 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgInt32 stackInt = (*(StgInt32*)Sp_plusW(1));
+ if (stackInt != (StgInt32)BCO_LIT(discr)) {
+ bciPtr = failto;
+ }
+ goto nextInsn;
+ }
+
+ case bci_TESTEQ_I16: {
+ // There should be an Int16 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgInt16 stackInt = (*(StgInt16*)Sp_plusW(1));
+ if (stackInt != (StgInt16)BCO_LIT(discr)) {
+ bciPtr = failto;
+ }
+ goto nextInsn;
+ }
+
+ case bci_TESTEQ_I8: {
+ // There should be an Int8 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgInt8 stackInt = (*(StgInt8*)Sp_plusW(1));
+ if (stackInt != (StgInt8)BCO_LIT(discr)) {
+ bciPtr = failto;
+ }
+ goto nextInsn;
+ }
+
case bci_TESTLT_W: {
- // There should be an Int at SpW(1), and an info table at SpW(0).
+ // There should be a Word at SpW(1), and an info table at SpW(0).
int discr = BCO_GET_LARGE_ARG;
int failto = BCO_GET_LARGE_ARG;
W_ stackWord = (W_)SpW(1);
@@ -1749,8 +1835,48 @@ run_BCO:
goto nextInsn;
}
+ case bci_TESTLT_W64: {
+ // There should be a Word64 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgWord64 stackWord = (*(StgWord64*)Sp_plusW(1));
+ if (stackWord >= BCO_LITW64(discr))
+ bciPtr = failto;
+ goto nextInsn;
+ }
+
+ case bci_TESTLT_W32: {
+ // There should be a Word32 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgWord32 stackWord = (*(StgWord32*)Sp_plusW(1));
+ if (stackWord >= (StgWord32)BCO_LIT(discr))
+ bciPtr = failto;
+ goto nextInsn;
+ }
+
+ case bci_TESTLT_W16: {
+ // There should be a Word16 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgWord16 stackWord = (*(StgWord16*)Sp_plusW(1));
+ if (stackWord >= (StgWord16)BCO_LIT(discr))
+ bciPtr = failto;
+ goto nextInsn;
+ }
+
+ case bci_TESTLT_W8: {
+ // There should be a Word8 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgWord8 stackWord = (*(StgWord8*)Sp_plusW(1));
+ if (stackWord >= (StgWord8)BCO_LIT(discr))
+ bciPtr = failto;
+ goto nextInsn;
+ }
+
case bci_TESTEQ_W: {
- // There should be an Int at SpW(1), and an info table at SpW(0).
+ // There should be a Word at SpW(1), and an info table at SpW(0).
int discr = BCO_GET_LARGE_ARG;
int failto = BCO_GET_LARGE_ARG;
W_ stackWord = (W_)SpW(1);
@@ -1760,6 +1886,50 @@ run_BCO:
goto nextInsn;
}
+ case bci_TESTEQ_W64: {
+ // There should be a Word64 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgWord64 stackWord = (*(StgWord64*)Sp_plusW(1));
+ if (stackWord != BCO_LITW64(discr)) {
+ bciPtr = failto;
+ }
+ goto nextInsn;
+ }
+
+ case bci_TESTEQ_W32: {
+ // There should be a Word32 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgWord32 stackWord = (*(StgWord32*)Sp_plusW(1));
+ if (stackWord != (StgWord32)BCO_LIT(discr)) {
+ bciPtr = failto;
+ }
+ goto nextInsn;
+ }
+
+ case bci_TESTEQ_W16: {
+ // There should be a Word16 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgWord16 stackWord = (*(StgWord16*)Sp_plusW(1));
+ if (stackWord != (StgWord16)BCO_LIT(discr)) {
+ bciPtr = failto;
+ }
+ goto nextInsn;
+ }
+
+ case bci_TESTEQ_W8: {
+ // There should be a Word8 at SpW(1), and an info table at SpW(0).
+ int discr = BCO_GET_LARGE_ARG;
+ int failto = BCO_GET_LARGE_ARG;
+ StgWord8 stackWord = (*(StgWord8*)Sp_plusW(1));
+ if (stackWord != (StgWord8)BCO_LIT(discr)) {
+ bciPtr = failto;
+ }
+ goto nextInsn;
+ }
+
case bci_TESTLT_D: {
// There should be a Double at SpW(1), and an info table at SpW(0).
int discr = BCO_GET_LARGE_ARG;