diff options
author | Luite Stegeman <stegeman@gmail.com> | 2023-01-03 12:06:48 +0900 |
---|---|---|
committer | Luite Stegeman <stegeman@gmail.com> | 2023-01-06 18:16:24 +0900 |
commit | 28f8c0ebbfe623784988745af75dcf3fdbdd3ca5 (patch) | |
tree | a9461a0de296bdd2dbe6cba66db866235ce2cba9 /rts/Interpreter.c | |
parent | b2a2db04b24a4654261db8e0db6ad7bac1b3d7cf (diff) | |
download | haskell-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.c | 174 |
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; |