Hello Dear Lispers,

my name is Patrick and I consider my lisp knowledge to be at an intermediate level. I am using SBCL, Slime and Emacs.

I am actually working on a program to play http://en.wikipedia.org/wiki/Score_Four. The calculations depends heavily on execution speed and short cuts.
​​
After severel steps at compilation-time a macro generates a very long function, that accesses an array B in the following way:

(defun xscore ()
(declare (optimize (speed 3) (safety 0))
((simple-array (integer 0 5) (4 4 4)) b)
((simple-array (integer 0 100000000) (21)) score-table))
(+
(AREF SCORE-TABLE
(+ (AREF B 0 3 0) (AREF B 0 2 0) (AREF B 0 1 0) (AREF B 0 0 0)))
(AREF SCORE-TABLE
(+ (AREF B 3 0 0) (AREF B 2 0 0) (AREF B 1 0 0) (AREF B 0 0 0)))
(AREF SCORE-TABLE
(+ (AREF B 1 3 0) (AREF B 1 2 0) (AREF B 1 1 0) (AREF B 1 0 0)))
(AREF SCORE-TABLE
(+ (AREF B 3 1 0) (AREF B 2 1 0) (AREF B 1 1 0) (AREF B 0 1 0)))

... plus some other hundreds of almost identical lines

))

This just sums up some array elements of B and looks up the sum in a SCORE-TABLE.

Dissassembling this shows me:

; 09DD316F:       488B05A2FFFFFF   MOV RAX, [RIP-94]          ; 'SCORE-TABLE
; no-arg-parsing entry point
;      176:       488B5021         MOV RDX, [RAX+33]
;      17A:       498B1414         MOV RDX, [R12+RDX]
;      17E:       4883FA61         CMP RDX, 97
;      182:       7504             JNE L0
;      184:       488B50F9         MOV RDX, [RAX-7]
;      188: L0:   488B0D91FFFFFF   MOV RCX, [RIP-111]         ; 'B
;      18F:       488B4121         MOV RAX, [RCX+33]
;      193:       498B0404         MOV RAX, [R12+RAX]
;      197:       4883F861         CMP RAX, 97
;      19B:       7504             JNE L1
;      19D:       488B41F9         MOV RAX, [RCX-7]
;      1A1: L1:   488B4011         MOV RAX, [RAX+17]
;      1A5:       488B4001         MOV RAX, [RAX+1]
;      1A9:       48C1E830         SHR RAX, 48
;      1AD:       4883E00F         AND RAX, 15
;      1B1:       488D0C00         LEA RCX, [RAX+RAX]
;      1B5:       488B1D64FFFFFF   MOV RBX, [RIP-156]         ; 'B
;      1BC:       488B4321         MOV RAX, [RBX+33]
;      1C0:       498B0404         MOV RAX, [R12+RAX]
;      1C4:       4883F861         CMP RAX, 97
;      1C8:       7504             JNE L2
;      1CA:       488B43F9         MOV RAX, [RBX-7]
;      1CE: L2:   488B4011         MOV RAX, [RAX+17]
;      1D2:       488B4001         MOV RAX, [RAX+1]
;      1D6:       48C1E820         SHR RAX, 32
;      1DA:       4883E00F         AND RAX, 15
;      1DE:       48D1E0           SHL RAX, 1
;      1E1:       4801C1           ADD RCX, RAX
;      1E4:       488B1D35FFFFFF   MOV RBX, [RIP-203]         ; 'B
;      1EB:       488B4321         MOV RAX, [RBX+33]
;      1EF:       498B0404         MOV RAX, [R12+RAX]
;      1F3:       4883F861         CMP RAX, 97
;      1F7:       7504             JNE L3
;      1F9:       488B43F9         MOV RAX, [RBX-7]
;      1FD: L3:   488B4011         MOV RAX, [RAX+17]
;      201:       488B4001         MOV RAX, [RAX+1]
;      205:       48C1E810         SHR RAX, 16
;      209:       4883E00F         AND RAX, 15
;      20D:       48D1E0           SHL RAX, 1
;      210:       4801C1           ADD RCX, RAX
;      213:       488B1D06FFFFFF   MOV RBX, [RIP-250]         ; 'B
;      21A:       488B4321         MOV RAX, [RBX+33]
;      21E:       498B0404         MOV RAX, [R12+RAX]
;      222:       4883F861         CMP RAX, 97
;      226:       7504             JNE L4
;      228:       488B43F9         MOV RAX, [RBX-7]
;      22C: L4:   488B4011         MOV RAX, [RAX+17]
;      230:       488B4001         MOV RAX, [RAX+1]
;      234:       4883E00F         AND RAX, 15
;      238:       48D1E0           SHL RAX, 1
;      23B:       4801C1           ADD RCX, RAX
;      23E:       8B544A01         MOV EDX, [RDX+RCX*2+1]
;      242:       48D1E2           SHL RDX, 1
;      245:       488B0DCCFEFFFF   MOV RCX, [RIP-308]         ; 'SCORE-TABLE
;      24C:       488B4121         MOV RAX, [RCX+33]
;      250:       498B0404         MOV RAX, [R12+RAX]
;      254:       4883F861         CMP RAX, 97
;      258:       7504             JNE L5
;      25A:       488B41F9         MOV RAX, [RCX-7]
;      25E: L5:   488B1DBBFEFFFF   MOV RBX, [RIP-325]         ; 'B
;      265:       488B4B21         MOV RCX, [RBX+33]
;      269:       498B0C0C         MOV RCX, [R12+RCX]
;      26D:       4883F961         CMP RCX, 97
;      271:       7504             JNE L6
;      273:       488B4BF9         MOV RCX, [RBX-7]
;      277: L6:   488B4911         MOV RCX, [RCX+17]
;      27B:       488B4919         MOV RCX, [RCX+25]
;      27F:       4883E10F         AND RCX, 15
;      283:       48D1E1           SHL RCX, 1
;      286:       488B3593FEFFFF   MOV RSI, [RIP-365]         ; 'B
;      28D:       488B5E21         MOV RBX, [RSI+33]
;      291:       498B1C1C         MOV RBX, [R12+RBX]
;      295:       4883FB61         CMP RBX, 97
;      299:       7504             JNE L7
;      29B:       488B5EF9         MOV RBX, [RSI-7]
;      29F: L7:   488B5B11         MOV RBX, [RBX+17]
;      2A3:       488B5B11         MOV RBX, [RBX+17]
;      2A7:       4883E30F         AND RBX, 15
;      2AB:       48D1E3           SHL RBX, 1
;      2AE:       488D3419         LEA RSI, [RCX+RBX]
;      2B2:       488B1D67FEFFFF   MOV RBX, [RIP-409]         ; 'B
;      2B9:       488B4B21         MOV RCX, [RBX+33]
;      2BD:       498B0C0C         MOV RCX, [R12+RCX]
;      2C1:       4883F961         CMP RCX, 97
;      2C5:       7504             JNE L8
;      2C7:       488B4BF9         MOV RCX, [RBX-7]
;      2CB: L8:   488B4911         MOV RCX, [RCX+17]
;      2CF:       488B4909         MOV RCX, [RCX+9]
;      2D3:       4883E10F         AND RCX, 15
;      2D7:       48D1E1           SHL RCX, 1
;      2DA:       4801CE           ADD RSI, RCX
;      2DD:       488B1D3CFEFFFF   MOV RBX, [RIP-452]         ; 'B
;      2E4:       488B4B21         MOV RCX, [RBX+33]
;      2E8:       498B0C0C         MOV RCX, [R12+RCX]

plus many more lines....

This does not seem quite optimal to me. I expected the compiler to generate code, that just accesses array b (possibly over some indirections) and sums the values up. Expecially I dont understand the instructions CMP RCX,97; JNE Lx.

What am I missing here? Is there a way to get simpler code?

kind regards,
Patrick