MCPcopy Create free account
hub / github.com/akyoto/q / executeBinaryOp

Method executeBinaryOp

src/codegen/executeBinaryOp.go:10–197  ·  view source on GitHub ↗
(step *Step, instr *ssa.BinaryOp)

Source from the content-addressed store, hash-verified

8 "git.urbach.dev/cli/q/src/ssa"
9 "git.urbach.dev/cli/q/src/token"
10 "git.urbach.dev/cli/q/src/types"
11)
12
13func (f *Function) executeBinaryOp(step *Step, instr *ssa.BinaryOp) {
14 if step.Register == -1 && !instr.Op.IsComparison() {
15 return
16 }
17
18 left := f.ValueToStep[instr.Left]
19 right := f.ValueToStep[instr.Right]
20 live := slices.Concat(step.Live, []*Step{left, right})
21 source := f.resolveOperand(left, live)
22 avoid := []cpu.Register{source}
23
24 if instr.Op == token.Div || instr.Op == token.Mod {
25 avoid = append(avoid, f.CPU.DivisorRestricted...)
26 }
27
28 operand := f.resolveOperand(right, live, avoid...)
29 destination := step.Register
30 isSpilled := f.isSpilled(destination)
31
32 if isSpilled {
33 avoid = append(avoid, operand)
34
35 if instr.Op == token.Shl || instr.Op == token.Shr {
36 avoid = append(avoid, f.CPU.ShiftRestricted...)
37 }
38
39 destination = f.findTempRegister(live, avoid...)
40 }
41
42 if instr.Op.IsComparison() {
43 f.emitComparison(step, left, right, source, operand, destination, instr.Op)
44 } else if isImmediate(right) {
45 f.emitArithmeticImmediate(left, source, destination, right.Value.(*ssa.Int).Int, instr.Op)
46 } else {
47 f.emitArithmeticRegister(left, source, operand, destination, instr.Op)
48 }
49
50 if isSpilled {
51 f.storeSpill(step, destination)
52 }
53}
54
55// emitComparison emits a compare followed by a conditional set when the result register is needed.
56func (f *Function) emitComparison(step *Step, left *Step, right *Step, source cpu.Register, operand cpu.Register, destination cpu.Register, op token.Kind) {
57 if isImmediate(right) {
58 f.Assembler.Append(&asm.CompareNumber{Destination: source, Number: right.Value.(*ssa.Int).Int})
59 } else {
60 f.Assembler.Append(&asm.Compare{Destination: source, Source: operand})
61 }
62
63 if step.Register != -1 {
64 unsigned := types.IsUnsigned(left.Value.Type()) || types.IsUnsigned(right.Value.Type())
65 f.conditionalSet(destination, op, unsigned)
66 }
67}

Callers 1

executeMethod · 0.95

Calls 6

conditionalSetMethod · 0.95
IsUnsignedFunction · 0.92
IsComparisonMethod · 0.80
TypeMethod · 0.65
StringMethod · 0.65
AppendMethod · 0.45

Tested by

no test coverage detected