return s.curBlock.NewValue1A(s.peekLine(), op, t, aux, arg)
}
+// newValue1I adds a new value with one argument and an auxint value to the current block.
+func (s *state) newValue1I(op ssa.Op, t ssa.Type, aux int64, arg *ssa.Value) *ssa.Value {
+ return s.curBlock.NewValue1I(s.peekLine(), op, t, aux, arg)
+}
+
// newValue2 adds a new value with two arguments to the current block.
func (s *state) newValue2(op ssa.Op, t ssa.Type, arg0, arg1 *ssa.Value) *ssa.Value {
return s.curBlock.NewValue2(s.peekLine(), op, t, arg0, arg1)
s.nilCheck(p)
return s.newValue2(ssa.OpLoad, n.Type, p, s.mem())
+ case ODOT:
+ v := s.expr(n.Left)
+ return s.newValue1I(ssa.OpStructSelect, n.Type, n.Xoffset, v)
+
case ODOTPTR:
p := s.expr(n.Left)
s.nilCheck(p)
// Note: bounds check has already been done
(ArrayIndex (Load ptr mem) idx) -> (Load (PtrIndex <v.Type.PtrTo()> ptr idx) mem)
(PtrIndex <t> ptr idx) -> (Add ptr (Mul <config.Uintptr> idx (Const <config.Uintptr> [t.Elem().Size()])))
+(StructSelect [idx] (Load ptr mem)) -> (Load (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
// big-object moves
// TODO: fix size
{name: "IsInBounds"}, // 0 <= arg0 < arg1
// Indexing operations
- {name: "ArrayIndex"}, // arg0=array, arg1=index. Returns a[i]
- {name: "PtrIndex"}, // arg0=ptr, arg1=index. Computes ptr+sizeof(*v.type)*index, where index is extended to ptrwidth type
- {name: "OffPtr"}, // arg0 + auxint (arg0 and result are pointers)
+ {name: "ArrayIndex"}, // arg0=array, arg1=index. Returns a[i]
+ {name: "PtrIndex"}, // arg0=ptr, arg1=index. Computes ptr+sizeof(*v.type)*index, where index is extended to ptrwidth type
+ {name: "OffPtr"}, // arg0 + auxint (arg0 and result are pointers)
+ {name: "StructSelect"}, // arg0=struct, auxint=field offset. Returns field at that offset (size=size of result type)
// Slices
{name: "SliceMake"}, // arg0=ptr, arg1=len, arg2=cap
OpArrayIndex
OpPtrIndex
OpOffPtr
+ OpStructSelect
OpSliceMake
OpSlicePtr
OpSliceLen
},
generic: true,
},
+ {
+ name: "StructSelect",
+ reg: regInfo{
+ inputs: []regMask{},
+ clobbers: 0,
+ outputs: []regMask{},
+ },
+ generic: true,
+ },
{
name: "SliceMake",
reg: regInfo{
}
goto end061edc5d85c73ad909089af2556d9380
end061edc5d85c73ad909089af2556d9380:
+ ;
+ case OpStructSelect:
+ // match: (StructSelect [idx] (Load ptr mem))
+ // cond:
+ // result: (Load (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
+ {
+ idx := v.AuxInt
+ if v.Args[0].Op != OpLoad {
+ goto end16fdb45e1dd08feb36e3cc3fb5ed8935
+ }
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[0].Args[1]
+ v.Op = OpLoad
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := v.Block.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v0.Type = v.Type.PtrTo()
+ v0.AuxInt = idx
+ v0.AddArg(ptr)
+ v.AddArg(v0)
+ v.AddArg(mem)
+ return true
+ }
+ goto end16fdb45e1dd08feb36e3cc3fb5ed8935
+ end16fdb45e1dd08feb36e3cc3fb5ed8935:
}
return false
}