Last active
September 19, 2024 04:09
-
-
Save guicho271828/e9436ae50b68bb2f6fa878280dea6b56 to your computer and use it in GitHub Desktop.
SBCL 1.5.9 jump-table compilation for `case` and nested `if` sequence
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; This also gets converted into a jump table | |
(defun fn (x) | |
(if (eql x #\a) | |
:a | |
(if (eql x #\b) | |
:b | |
(if (eql x #\c) | |
:c | |
(if (eql x #\d) | |
:d))))) | |
;; This also gets converted into a jump table | |
(defun fn (x) | |
(tagbody | |
(if (eql x #\a) | |
(go :a) | |
(go :-a)) | |
:a | |
(return-from fn :a) | |
:-a | |
(if (eql x #\b) | |
(go :b) | |
(go :-b)) | |
:b | |
(return-from fn :b) | |
:-b | |
(if (eql x #\c) | |
(go :c) | |
(go :-c)) | |
:c | |
(return-from fn :c) | |
:-c | |
(if (eql x #\d) | |
(go :d) | |
(go :-d)) | |
:d | |
(return-from fn :d) | |
:-d | |
nil)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun fn (x) | |
(case x | |
(1 (print :one)) | |
(2 (print :two)) | |
(3 (print :three)) | |
(4 (print :four)))) | |
; disassembly for FN | |
; Size: 127 bytes. Origin: #x52D42C04 ; FN | |
; 04: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer | |
; 08: 488945F8 MOV [RBP-8], RAX | |
; 0C: 4C8D5BFE LEA R11, [RBX-2] | |
; 10: 4983FB06 CMP R11, 6 | |
; 14: 7710 JNBE L0 | |
; 16: F6C301 TEST BL, 1 | |
; 19: 750B JNE L0 | |
; 1B: 488D059EFFFFFF LEA RAX, [RIP-98] ; = #x52D42BC0 | |
; 22: 42FF2498 JMP QWORD PTR [RAX+R11*4] | |
; 26: L0: BA17001050 MOV EDX, #x50100017 ; NIL | |
; 2B: 488BE5 MOV RSP, RBP | |
; 2E: F8 CLC | |
; 2F: 5D POP RBP | |
; 30: C3 RET | |
; 31: L1: BA0FC34F50 MOV EDX, #x504FC30F ; :FOUR | |
; 36: B902000000 MOV ECX, 2 | |
; 3B: FF7508 PUSH QWORD PTR [RBP+8] | |
; 3E: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; 43: FFE0 JMP RAX | |
; 45: L2: BADFC24F50 MOV EDX, #x504FC2DF ; :THREE | |
; 4A: B902000000 MOV ECX, 2 | |
; 4F: FF7508 PUSH QWORD PTR [RBP+8] | |
; 52: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; 57: FFE0 JMP RAX | |
; 59: L3: BA7FC24F50 MOV EDX, #x504FC27F ; :TWO | |
; 5E: B902000000 MOV ECX, 2 | |
; 63: FF7508 PUSH QWORD PTR [RBP+8] | |
; 66: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; 6B: FFE0 JMP RAX | |
; 6D: L4: BA4FC24F50 MOV EDX, #x504FC24F ; :ONE | |
; 72: B902000000 MOV ECX, 2 | |
; 77: FF7508 PUSH QWORD PTR [RBP+8] | |
; 7A: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; 7F: FFE0 JMP RAX | |
; 81: CC10 INT3 16 ; Invalid argument count trap | |
;; nested IF + eql | |
(defun fn (x) | |
(if (eql x 1) | |
(print :one) | |
(if (eql x 2) | |
(print :two) | |
(if (eql x 3) | |
(print :three) | |
(if (eql x 4) | |
(print :four) | |
nil))))) | |
; disassembly for FN | |
; Size: 127 bytes. Origin: #x52D699F4 ; FN | |
; 9F4: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer | |
; 9F8: 488945F8 MOV [RBP-8], RAX | |
; 9FC: 4C8D5BFE LEA R11, [RBX-2] | |
; A00: 4983FB06 CMP R11, 6 | |
; A04: 7710 JNBE L0 | |
; A06: F6C301 TEST BL, 1 | |
; A09: 750B JNE L0 | |
; A0B: 488D059EFFFFFF LEA RAX, [RIP-98] ; = #x52D699B0 | |
; A12: 42FF2498 JMP QWORD PTR [RAX+R11*4] | |
; A16: L0: BA17001050 MOV EDX, #x50100017 ; NIL | |
; A1B: 488BE5 MOV RSP, RBP | |
; A1E: F8 CLC | |
; A1F: 5D POP RBP | |
; A20: C3 RET | |
; A21: L1: BA0FC34F50 MOV EDX, #x504FC30F ; :FOUR | |
; A26: B902000000 MOV ECX, 2 | |
; A2B: FF7508 PUSH QWORD PTR [RBP+8] | |
; A2E: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; A33: FFE0 JMP RAX | |
; A35: L2: BADFC24F50 MOV EDX, #x504FC2DF ; :THREE | |
; A3A: B902000000 MOV ECX, 2 | |
; A3F: FF7508 PUSH QWORD PTR [RBP+8] | |
; A42: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; A47: FFE0 JMP RAX | |
; A49: L3: BA7FC24F50 MOV EDX, #x504FC27F ; :TWO | |
; A4E: B902000000 MOV ECX, 2 | |
; A53: FF7508 PUSH QWORD PTR [RBP+8] | |
; A56: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; A5B: FFE0 JMP RAX | |
; A5D: L4: BA4FC24F50 MOV EDX, #x504FC24F ; :ONE | |
; A62: B902000000 MOV ECX, 2 | |
; A67: FF7508 PUSH QWORD PTR [RBP+8] | |
; A6A: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; A6F: FFE0 JMP RAX | |
; A71: CC10 INT3 16 ; Invalid argument count trap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun fn (x) | |
(case x | |
(1 (print :one)) | |
(2 (print :two)) | |
(:three (print :three)) | |
(4 (print :four)))) | |
; disassembly for FN | |
; Size: 128 bytes. Origin: #x52D69434 ; FN | |
; 34: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer | |
; 38: 488945F8 MOV [RBP-8], RAX | |
; 3C: 4883FB02 CMP RBX, 2 | |
; 40: 745C JEQ L3 | |
; 42: 4883FB04 CMP RBX, 4 | |
; 46: 7442 JEQ L2 | |
; 48: 4881FBDFC24F50 CMP RBX, #x504FC2DF ; :THREE | |
; 4F: 7425 JEQ L1 | |
; 51: 4883FB08 CMP RBX, 8 | |
; 55: 740B JEQ L0 | |
; 57: BA17001050 MOV EDX, #x50100017 ; NIL | |
; 5C: 488BE5 MOV RSP, RBP | |
; 5F: F8 CLC | |
; 60: 5D POP RBP | |
; 61: C3 RET | |
; 62: L0: BA0FC34F50 MOV EDX, #x504FC30F ; :FOUR | |
; 67: B902000000 MOV ECX, 2 | |
; 6C: FF7508 PUSH QWORD PTR [RBP+8] | |
; 6F: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; 74: FFE0 JMP RAX | |
; 76: L1: BADFC24F50 MOV EDX, #x504FC2DF ; :THREE | |
; 7B: B902000000 MOV ECX, 2 | |
; 80: FF7508 PUSH QWORD PTR [RBP+8] | |
; 83: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; 88: FFE0 JMP RAX | |
; 8A: L2: BA7FC24F50 MOV EDX, #x504FC27F ; :TWO | |
; 8F: B902000000 MOV ECX, 2 | |
; 94: FF7508 PUSH QWORD PTR [RBP+8] | |
; 97: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; 9C: FFE0 JMP RAX | |
; 9E: L3: BA4FC24F50 MOV EDX, #x504FC24F ; :ONE | |
; A3: B902000000 MOV ECX, 2 | |
; A8: FF7508 PUSH QWORD PTR [RBP+8] | |
; AB: B8C2664850 MOV EAX, #x504866C2 ; #<FDEFN PRINT> | |
; B0: FFE0 JMP RAX | |
; B2: CC10 INT3 16 ; Invalid argument count trap | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; equivalent code in Trivia pattern matcher does not get compiled into a jump table | |
(defun fn (x) | |
(match x | |
(#\a :a) | |
(#\b :b) | |
(#\c :c) | |
(#\d :d))) | |
; note: above code expands into | |
(SYMBOL-MACROLET ((#:ARG1283 X)) | |
(DECLARE) | |
(LET ((#:WHAT11298 #:ARG1283)) | |
(DECLARE (IGNORABLE #:WHAT11298)) | |
(BLOCK TRIVIA.LEVEL1.IMPL::WHOLE | |
(BLOCK TRIVIA.LEVEL1.IMPL::CLAUSE ; 1 | |
(LET ((#:IT1284 #:WHAT11298)) | |
(DECLARE (IGNORABLE #:IT1284)) | |
(WHEN (EQL #:IT1284 #\a) | |
(LOCALLY | |
(DECLARE (TYPE (EQL #\a) #:IT1284)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE | |
(LOCALLY | |
(LET ((#:WHAT11308 NIL)) | |
(DECLARE (IGNORABLE #:WHAT11308)) | |
(BLOCK TRIVIA.LEVEL1.IMPL::WHOLE | |
(BLOCK TRIVIA.LEVEL1.IMPL::CLAUSE | |
(LET ((#:IT1289 #:WHAT11308)) | |
(DECLARE (IGNORABLE #:IT1289)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE (LOCALLY :A)))) | |
(LET ((#:IT1290 #:WHAT11308)) | |
(DECLARE (IGNORABLE #:IT1290)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE | |
(LOCALLY (RETURN-FROM TRIVIA.LEVEL1.IMPL::CLAUSE NIL)))))))))))) ; jumps back to 1 | |
(BLOCK TRIVIA.LEVEL1.IMPL::CLAUSE ; 2 | |
(LET ((#:IT1285 #:WHAT11298)) | |
(DECLARE (IGNORABLE #:IT1285)) | |
(WHEN (EQL #:IT1285 #\b) | |
(LOCALLY | |
(DECLARE (TYPE (EQL #\b) #:IT1285)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE | |
(LOCALLY | |
(LET ((#:WHAT11309 NIL)) | |
(DECLARE (IGNORABLE #:WHAT11309)) | |
(BLOCK TRIVIA.LEVEL1.IMPL::WHOLE | |
(BLOCK TRIVIA.LEVEL1.IMPL::CLAUSE | |
(LET ((#:IT1291 #:WHAT11309)) | |
(DECLARE (IGNORABLE #:IT1291)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE (LOCALLY :B)))) | |
(LET ((#:IT1292 #:WHAT11309)) | |
(DECLARE (IGNORABLE #:IT1292)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE (LOCALLY (RETURN-FROM TRIVIA.LEVEL1.IMPL::CLAUSE NIL)))))))))))) ; jump back to 2 | |
(BLOCK TRIVIA.LEVEL1.IMPL::CLAUSE | |
(LET ((#:IT1286 #:WHAT11298)) | |
(DECLARE (IGNORABLE #:IT1286)) | |
(WHEN (EQL #:IT1286 #\c) | |
(LOCALLY | |
(DECLARE (TYPE (EQL #\c) #:IT1286)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE | |
(LOCALLY | |
(LET ((#:WHAT11310 NIL)) | |
(DECLARE (IGNORABLE #:WHAT11310)) | |
(BLOCK TRIVIA.LEVEL1.IMPL::WHOLE | |
(BLOCK TRIVIA.LEVEL1.IMPL::CLAUSE | |
(LET ((#:IT1293 #:WHAT11310)) | |
(DECLARE (IGNORABLE #:IT1293)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE (LOCALLY :C)))) | |
(LET ((#:IT1294 #:WHAT11310)) | |
(DECLARE (IGNORABLE #:IT1294)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE (LOCALLY (RETURN-FROM TRIVIA.LEVEL1.IMPL::CLAUSE NIL)))))))))))) | |
(BLOCK TRIVIA.LEVEL1.IMPL::CLAUSE | |
(LET ((#:IT1287 #:WHAT11298)) | |
(DECLARE (IGNORABLE #:IT1287)) | |
(WHEN (EQL #:IT1287 #\d) | |
(LOCALLY | |
(DECLARE (TYPE (EQL #\d) #:IT1287)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE | |
(LOCALLY | |
(LET ((#:WHAT11311 NIL)) | |
(DECLARE (IGNORABLE #:WHAT11311)) | |
(BLOCK TRIVIA.LEVEL1.IMPL::WHOLE | |
(BLOCK TRIVIA.LEVEL1.IMPL::CLAUSE | |
(LET ((#:IT1295 #:WHAT11311)) | |
(DECLARE (IGNORABLE #:IT1295)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE (LOCALLY :D)))) | |
(LET ((#:IT1296 #:WHAT11311)) | |
(DECLARE (IGNORABLE #:IT1296)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE (LOCALLY (RETURN-FROM TRIVIA.LEVEL1.IMPL::CLAUSE NIL)))))))))))) | |
(LET ((#:IT1288 #:WHAT11298)) | |
(DECLARE (IGNORABLE #:IT1288)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE | |
(LOCALLY | |
(LET ((#:WHAT11312 NIL)) | |
(DECLARE (IGNORABLE #:WHAT11312)) | |
(BLOCK TRIVIA.LEVEL1.IMPL::WHOLE | |
(LET ((#:IT1297 #:WHAT11312)) | |
(DECLARE (IGNORABLE #:IT1297)) | |
(RETURN-FROM TRIVIA.LEVEL1.IMPL::WHOLE (LOCALLY NIL))))))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment