func emitRbrac(asm *amd64.Assembler, cc *compiled) { header := cc.stack[len(cc.stack)-1] cc.stack = cc.stack[:len(cc.stack)-1] asm.JmpRel(gojit.Addr(asm.Buf[header:])) end := asm.Off asm.Off = header asm.Testb(amd64.Imm{0xff}, amd64.Indirect{amd64.Rax, 0, 8}) asm.JccRel(amd64.CC_Z, gojit.Addr(asm.Buf[end:])) asm.Off = end }
func jcc(a *amd64.Assembler, cc byte, over func(*amd64.Assembler)) { start := a.Off a.JccShort(cc, 0) base := a.Off over(a) end := a.Off a.Off = start if int(int8(end-base)) != end-base { panic("jcc: too far!") } a.JccShort(cc, int8(end-base)) a.Off = end }
func emitComma(asm *amd64.Assembler, cc *compiled) { asm.Push(amd64.Rax) asm.Sub(amd64.Imm{48}, amd64.Rsp) asm.Mov(amd64.Imm{1}, amd64.Indirect{amd64.Rsp, 16, 64}) asm.Mov(amd64.Imm{1}, amd64.Indirect{amd64.Rsp, 8, 64}) asm.Mov(amd64.Rax, amd64.Indirect{amd64.Rsp, 0, 64}) asm.CallFunc(cc.r) asm.Add(amd64.Imm{48}, amd64.Rsp) asm.Pop(amd64.Rax) asm.Test(amd64.Imm{-1}, amd64.Indirect{amd64.Rsp, -24, 64}) jcc(asm, amd64.CC_Z, func(asm *amd64.Assembler) { asm.Movb(amd64.Imm{0}, amd64.Indirect{amd64.Rax, 0, 8}) }) }
func emitDot(asm *amd64.Assembler, cc *compiled) { asm.Push(amd64.Rax) asm.Sub(amd64.Imm{48}, amd64.Rsp) asm.Mov(amd64.Imm{1}, amd64.Indirect{amd64.Rsp, 16, 64}) asm.Mov(amd64.Imm{1}, amd64.Indirect{amd64.Rsp, 8, 64}) asm.Mov(amd64.Rax, amd64.Indirect{amd64.Rsp, 0, 64}) asm.CallFunc(cc.w) asm.Add(amd64.Imm{48}, amd64.Rsp) asm.Pop(amd64.Rax) }
func emitLbrac(asm *amd64.Assembler, cc *compiled) { cc.stack = append(cc.stack, asm.Off) asm.Testb(amd64.Imm{0xff}, amd64.Indirect{amd64.Rax, 0, 8}) asm.JccRel(amd64.CC_Z, gojit.Addr(asm.Buf[asm.Off:])) }