本文整理匯總了Golang中bootstrap/internal/obj.Link.Diag方法的典型用法代碼示例。如果您正苦於以下問題:Golang Link.Diag方法的具體用法?Golang Link.Diag怎麽用?Golang Link.Diag使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類bootstrap/internal/obj.Link
的用法示例。
在下文中一共展示了Link.Diag方法的14個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: nacladdr
func nacladdr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
if p.As == ALEAL || p.As == ALEAQ {
return
}
if a.Reg == REG_BP {
ctxt.Diag("invalid address: %v", p)
return
}
if a.Reg == REG_TLS {
a.Reg = REG_BP
}
if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE {
switch a.Reg {
// all ok
case REG_BP, REG_SP, REG_R15:
break
default:
if a.Index != REG_NONE {
ctxt.Diag("invalid address %v", p)
}
a.Index = a.Reg
if a.Index != REG_NONE {
a.Scale = 1
}
a.Reg = REG_R15
}
}
}
示例2: oplook
func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
if oprange[AOR&obj.AMask].start == nil {
buildop(ctxt)
}
a1 := int(p.Optab)
if a1 != 0 {
return &optab[a1-1:][0]
}
a1 = int(p.From.Class)
if a1 == 0 {
a1 = aclass(ctxt, &p.From) + 1
p.From.Class = int8(a1)
}
a1--
a3 := int(p.To.Class)
if a3 == 0 {
a3 = aclass(ctxt, &p.To) + 1
p.To.Class = int8(a3)
}
a3--
a2 := C_NONE
if p.Reg != 0 {
a2 = C_REG
}
//print("oplook %P %d %d %d\n", p, a1, a2, a3);
r0 := p.As & obj.AMask
o := oprange[r0].start
if o == nil {
o = oprange[r0].stop /* just generate an error */
}
e := oprange[r0].stop
c1 := xcmp[a1][:]
c3 := xcmp[a3][:]
for ; -cap(o) < -cap(e); o = o[1:] {
if int(o[0].a2) == a2 {
if c1[o[0].a1] != 0 {
if c3[o[0].a3] != 0 {
p.Optab = uint16((-cap(o) + cap(optab)) + 1)
return &o[0]
}
}
}
}
ctxt.Diag("illegal combination %v %v %v %v", obj.Aconv(int(p.As)), DRconv(a1), DRconv(a2), DRconv(a3))
prasm(p)
if o == nil {
o = optab
}
return &o[0]
}
示例3: progedit
func progedit(ctxt *obj.Link, p *obj.Prog) {
p.From.Class = 0
p.To.Class = 0
// Rewrite B/BL to symbol as TYPE_BRANCH.
switch p.As {
case AB,
ABL,
obj.ADUFFZERO,
obj.ADUFFCOPY:
if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil {
p.To.Type = obj.TYPE_BRANCH
}
}
// Replace TLS register fetches on older ARM procesors.
switch p.As {
// Treat MRC 15, 0, <reg>, C13, C0, 3 specially.
case AMRC:
if p.To.Offset&0xffff0fff == 0xee1d0f70 {
// Because the instruction might be rewriten to a BL which returns in R0
// the register must be zero.
if p.To.Offset&0xf000 != 0 {
ctxt.Diag("%v: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p.Line())
}
if ctxt.Goarm < 7 {
// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
if progedit_tlsfallback == nil {
progedit_tlsfallback = obj.Linklookup(ctxt, "runtime.read_tls_fallback", 0)
}
// MOVW LR, R11
p.As = AMOVW
p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK
p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP
// BL runtime.read_tls_fallback(SB)
p = obj.Appendp(ctxt, p)
p.As = ABL
p.To.Type = obj.TYPE_BRANCH
p.To.Sym = progedit_tlsfallback
p.To.Offset = 0
// MOVW R11, LR
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP
p.To.Type = obj.TYPE_REG
p.To.Reg = REGLINK
break
}
}
// Otherwise, MRC/MCR instructions need no further treatment.
p.As = AWORD
}
// Rewrite float constants to values stored in memory.
switch p.As {
case AMOVF:
if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.Val.(float64)) < 0 && (chipzero5(ctxt, p.From.Val.(float64)) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
f32 := float32(p.From.Val.(float64))
i32 := math.Float32bits(f32)
literal := fmt.Sprintf("$f32.%08x", i32)
s := obj.Linklookup(ctxt, literal, 0)
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
case AMOVD:
if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.Val.(float64)) < 0 && (chipzero5(ctxt, p.From.Val.(float64)) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
i64 := math.Float64bits(p.From.Val.(float64))
literal := fmt.Sprintf("$f64.%016x", i64)
s := obj.Linklookup(ctxt, literal, 0)
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
}
if ctxt.Flag_dynlink {
rewriteToUseGot(ctxt, p)
}
}
示例4: preprocess
//.........這裏部分代碼省略.........
p.As = AMOVW
p.Scond |= C_PBIT
p.From.Type = obj.TYPE_MEM
p.From.Offset = int64(autosize)
p.From.Reg = REGSP
p.To.Type = obj.TYPE_REG
p.To.Reg = REGPC
// If there are instructions following
// this ARET, they come from a branch
// with the same stackframe, so no spadj.
if p.To.Sym != nil { // retjmp
p.To.Reg = REGLINK
q2 = obj.Appendp(ctxt, p)
q2.As = AB
q2.To.Type = obj.TYPE_BRANCH
q2.To.Sym = p.To.Sym
p.To.Sym = nil
p = q2
}
case AADD:
if p.From.Type == obj.TYPE_CONST && p.From.Reg == 0 && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP {
p.Spadj = int32(-p.From.Offset)
}
case ASUB:
if p.From.Type == obj.TYPE_CONST && p.From.Reg == 0 && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP {
p.Spadj = int32(p.From.Offset)
}
case ADIV, ADIVU, AMOD, AMODU:
if cursym.Text.From3.Offset&obj.NOSPLIT != 0 {
ctxt.Diag("cannot divide in NOSPLIT function")
}
if ctxt.Debugdivmod != 0 {
break
}
if p.From.Type != obj.TYPE_REG {
break
}
if p.To.Type != obj.TYPE_REG {
break
}
// Make copy because we overwrite p below.
q1 := *p
if q1.Reg == REGTMP || q1.Reg == 0 && q1.To.Reg == REGTMP {
ctxt.Diag("div already using REGTMP: %v", p)
}
/* MOV m(g),REGTMP */
p.As = AMOVW
p.Lineno = q1.Lineno
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 6 * 4 // offset of g.m
p.Reg = 0
p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP
/* MOV a,m_divmod(REGTMP) */
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.Lineno = q1.Lineno
p.From.Type = obj.TYPE_REG
示例5: rewriteToUseGot
// Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
// ADUFFxxx $offset
// becomes
// MOVW [email protected], R9
// ADD $offset, R9
// CALL (R9)
var sym *obj.LSym
if p.As == obj.ADUFFZERO {
sym = obj.Linklookup(ctxt, "runtime.duffzero", 0)
} else {
sym = obj.Linklookup(ctxt, "runtime.duffcopy", 0)
}
offset := p.To.Offset
p.As = AMOVW
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF
p.From.Sym = sym
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R9
p.To.Name = obj.NAME_NONE
p.To.Offset = 0
p.To.Sym = nil
p1 := obj.Appendp(ctxt, p)
p1.As = AADD
p1.From.Type = obj.TYPE_CONST
p1.From.Offset = offset
p1.To.Type = obj.TYPE_REG
p1.To.Reg = REG_R9
p2 := obj.Appendp(ctxt, p1)
p2.As = obj.ACALL
p2.To.Type = obj.TYPE_MEM
p2.To.Reg = REG_R9
return
}
// We only care about global data: NAME_EXTERN means a global
// symbol in the Go sense, and p.Sym.Local is true for a few
// internally defined symbols.
if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
// MOVW $sym, Rx becomes MOVW [email protected], Rx
// MOVW $sym+<off>, Rx becomes MOVW [email protected], Rx; ADD <off>, Rx
if p.As != AMOVW {
ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p)
}
if p.To.Type != obj.TYPE_REG {
ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p)
}
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF
if p.From.Offset != 0 {
q := obj.Appendp(ctxt, p)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset
q.To = p.To
p.From.Offset = 0
}
}
if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
var source *obj.Addr
// MOVx sym, Ry becomes MOVW [email protected], R9; MOVx (R9), Ry
// MOVx Ry, sym becomes MOVW [email protected], R9; MOVx Ry, (R9)
// An addition may be inserted between the two MOVs if there is an offset.
if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
}
source = &p.From
} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
source = &p.To
} else {
return
}
if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP {
return
}
if source.Sym.Type == obj.STLSBSS {
return
}
if source.Type != obj.TYPE_MEM {
ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
p1 := obj.Appendp(ctxt, p)
p2 := obj.Appendp(ctxt, p1)
p1.As = AMOVW
p1.From.Type = obj.TYPE_MEM
p1.From.Sym = source.Sym
p1.From.Name = obj.NAME_GOTREF
p1.To.Type = obj.TYPE_REG
p1.To.Reg = REG_R9
p2.As = p.As
p2.From = p.From
p2.To = p.To
if p.From.Name == obj.NAME_EXTERN {
//.........這裏部分代碼省略.........
示例6: rewriteToUseGot
// Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
var add, lea, mov, reg int16
if p.Mode == 64 {
add = AADDQ
lea = ALEAQ
mov = AMOVQ
reg = REG_R15
} else {
add = AADDL
lea = ALEAL
mov = AMOVL
reg = REG_CX
}
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
// ADUFFxxx $offset
// becomes
// $MOV [email protected], $reg
// $ADD $offset, $reg
// CALL $reg
var sym *obj.LSym
if p.As == obj.ADUFFZERO {
sym = obj.Linklookup(ctxt, "runtime.duffzero", 0)
} else {
sym = obj.Linklookup(ctxt, "runtime.duffcopy", 0)
}
offset := p.To.Offset
p.As = mov
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF
p.From.Sym = sym
p.To.Type = obj.TYPE_REG
p.To.Reg = reg
p.To.Offset = 0
p.To.Sym = nil
p1 := obj.Appendp(ctxt, p)
p1.As = add
p1.From.Type = obj.TYPE_CONST
p1.From.Offset = offset
p1.To.Type = obj.TYPE_REG
p1.To.Reg = reg
p2 := obj.Appendp(ctxt, p1)
p2.As = obj.ACALL
p2.To.Type = obj.TYPE_REG
p2.To.Reg = reg
}
// We only care about global data: NAME_EXTERN means a global
// symbol in the Go sense, and p.Sym.Local is true for a few
// internally defined symbols.
if p.As == lea && p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
// $LEA sym, Rx becomes $MOV $sym, Rx which will be rewritten below
p.As = mov
p.From.Type = obj.TYPE_ADDR
}
if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
// $MOV $sym, Rx becomes $MOV [email protected], Rx
// $MOV $sym+<off>, Rx becomes $MOV [email protected], Rx; $ADD <off>, Rx
// On 386 only, more complicated things like PUSHL $sym become $MOV [email protected], CX; PUSHL CX
cmplxdest := false
pAs := p.As
var dest obj.Addr
if p.To.Type != obj.TYPE_REG || pAs != mov {
if p.Mode == 64 {
ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p)
}
cmplxdest = true
dest = p.To
p.As = mov
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_CX
p.To.Sym = nil
p.To.Name = obj.NAME_NONE
}
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF
q := p
if p.From.Offset != 0 {
q = obj.Appendp(ctxt, p)
q.As = add
q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset
q.To = p.To
p.From.Offset = 0
}
if cmplxdest {
q = obj.Appendp(ctxt, q)
q.As = pAs
q.To = dest
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_CX
}
}
if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
var source *obj.Addr
// MOVx sym, Ry becomes $MOV [email protected], R15; MOVx (R15), Ry
// MOVx Ry, sym becomes $MOV [email protected], R15; MOVx Ry, (R15)
//.........這裏部分代碼省略.........
示例7: preprocess
//.........這裏部分代碼省略.........
}
q = p
}
var o int
var q2 *obj.Prog
var retjmp *obj.LSym
for p := cursym.Text; p != nil; p = p.Link {
o = int(p.As)
switch o {
case obj.ATEXT:
cursym.Text = p
if textstksiz < 0 {
ctxt.Autosize = 0
} else {
ctxt.Autosize = int32(textstksiz + 8)
}
if (cursym.Text.Mark&LEAF != 0) && ctxt.Autosize <= 8 {
ctxt.Autosize = 0
} else if ctxt.Autosize&(16-1) != 0 {
// The frame includes an LR.
// If the frame size is 8, it's only an LR,
// so there's no potential for breaking references to
// local variables by growing the frame size,
// because there are no local variables.
// But otherwise, if there is a non-empty locals section,
// the author of the code is responsible for making sure
// that the frame size is 8 mod 16.
if ctxt.Autosize == 8 {
ctxt.Autosize += 8
cursym.Locals += 8
} else {
ctxt.Diag("%v: unaligned frame size %d - must be 8 mod 16 (or 0)", p, ctxt.Autosize-8)
}
}
p.To.Offset = int64(ctxt.Autosize) - 8
if ctxt.Autosize == 0 && !(cursym.Text.Mark&LEAF != 0) {
if ctxt.Debugvlog != 0 {
fmt.Fprintf(ctxt.Bso, "save suppressed in: %s\n", cursym.Text.From.Sym.Name)
}
ctxt.Bso.Flush()
cursym.Text.Mark |= LEAF
}
if !(p.From3.Offset&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, ctxt.Autosize) // emit split check
}
aoffset = ctxt.Autosize
if aoffset > 0xF0 {
aoffset = 0xF0
}
if cursym.Text.Mark&LEAF != 0 {
cursym.Leaf = 1
if ctxt.Autosize == 0 {
break
}
aoffset = 0
}
q = p
if ctxt.Autosize > aoffset {
q = ctxt.NewProg()
q.As = ASUB
q.Lineno = p.Lineno
示例8: preprocess
//.........這裏部分代碼省略.........
q.As = ABNE
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2
q.Reg = REG_R3
q.To.Type = obj.TYPE_BRANCH
q.Mark |= BRANCH
p2 = q
q = obj.Appendp(ctxt, q)
q.As = AADDV
q.From.Type = obj.TYPE_CONST
q.From.Offset = 8
q.Reg = REGSP
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R2
q = obj.Appendp(ctxt, q)
q.As = AMOVV
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2
q.To.Type = obj.TYPE_MEM
q.To.Reg = REG_R1
q.To.Offset = 0 // Panic.argp
q = obj.Appendp(ctxt, q)
q.As = obj.ANOP
p1.Pcond = q
p2.Pcond = q
}
case ARET:
if p.From.Type == obj.TYPE_CONST {
ctxt.Diag("using BECOME (%v) is not supported!", p)
break
}
if p.To.Sym != nil { // retjmp
p.As = AJMP
p.To.Type = obj.TYPE_BRANCH
break
}
if cursym.Text.Mark&LEAF != 0 {
if autosize == 0 {
p.As = AJMP
p.From = obj.Addr{}
p.To.Type = obj.TYPE_MEM
p.To.Offset = 0
p.To.Reg = REGLINK
p.Mark |= BRANCH
break
}
p.As = AADDV
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize)
p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP
p.Spadj = -autosize
q = ctxt.NewProg()
q.As = AJMP
q.Lineno = p.Lineno
q.To.Type = obj.TYPE_MEM
q.To.Offset = 0
示例9: asmout
func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 := uint32(0)
o2 := uint32(0)
o3 := uint32(0)
o4 := uint32(0)
switch o.type_ {
default:
ctxt.Diag("unknown type %d %v", o.type_)
prasm(p)
case 0: /* pseudo ops */
break
case 1: /* mov r1,r2 ==> OR r1,r0,r2 */
o1 = OP_RRR(oprrr(ctxt, AOR), uint32(p.From.Reg), uint32(REGZERO), uint32(p.To.Reg))
case 2: /* add/sub r1,[r2],r3 */
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
}
o1 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
case 3: /* mov $soreg, r ==> or/add $i,o,r */
v := regoff(ctxt, &p.From)
r := int(p.From.Reg)
if r == 0 {
r = int(o.param)
}
a := AADDVU
if o.a1 == C_ANDCON {
a = AOR
}
o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg))
case 4: /* add $scon,[r1],r2 */
v := regoff(ctxt, &p.From)
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
}
o1 = OP_IRR(opirr(ctxt, int(p.As)), uint32(v), uint32(r), uint32(p.To.Reg))
case 5: /* syscall */
o1 = uint32(oprrr(ctxt, int(p.As)))
case 6: /* beq r1,[r2],sbra */
v := int32(0)
if p.Pcond == nil {
v = int32(-4) >> 2
} else {
v = int32(p.Pcond.Pc-p.Pc-4) >> 2
}
if (v<<16)>>16 != v {
ctxt.Diag("short branch too far\n%v", p)
}
o1 = OP_IRR(opirr(ctxt, int(p.As)), uint32(v), uint32(p.From.Reg), uint32(p.Reg))
// for ABFPT and ABFPF only: always fill delay slot with 0
// see comments in func preprocess for details.
o2 = 0
case 7: /* mov r, soreg ==> sw o(r) */
r := int(p.To.Reg)
if r == 0 {
r = int(o.param)
}
v := regoff(ctxt, &p.To)
o1 = OP_IRR(opirr(ctxt, int(p.As)), uint32(v), uint32(r), uint32(p.From.Reg))
case 8: /* mov soreg, r ==> lw o(r) */
r := int(p.From.Reg)
if r == 0 {
r = int(o.param)
}
v := regoff(ctxt, &p.From)
o1 = OP_IRR(opirr(ctxt, int(p.As)+ALAST), uint32(v), uint32(r), uint32(p.To.Reg))
case 9: /* sll r1,[r2],r3 */
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
}
o1 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
case 10: /* add $con,[r1],r2 ==> mov $con, t; add t,[r1],r2 */
v := regoff(ctxt, &p.From)
a := AOR
if v < 0 {
a = AADDU
}
o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP))
r := int(p.Reg)
if r == 0 {
//.........這裏部分代碼省略.........
示例10: buildop
func buildop(ctxt *obj.Link) {
var n int
for i := 0; i < C_NCLASS; i++ {
for n = 0; n < C_NCLASS; n++ {
if cmp(n, i) {
xcmp[i][n] = 1
}
}
}
for n = 0; optab[n].as != obj.AXXX; n++ {
}
sort.Sort(ocmp(optab[:n]))
for i := 0; i < n; i++ {
r := optab[i].as
r0 := r & obj.AMask
oprange[r0].start = optab[i:]
for optab[i].as == r {
i++
}
oprange[r0].stop = optab[i:]
i--
switch r {
default:
ctxt.Diag("unknown op in build: %v", obj.Aconv(int(r)))
log.Fatalf("bad code")
case AABSF:
opset(AMOVFD, r0)
opset(AMOVDF, r0)
opset(AMOVWF, r0)
opset(AMOVFW, r0)
opset(AMOVWD, r0)
opset(AMOVDW, r0)
opset(ANEGF, r0)
opset(ANEGD, r0)
opset(AABSD, r0)
opset(ATRUNCDW, r0)
opset(ATRUNCFW, r0)
opset(ATRUNCDV, r0)
opset(ATRUNCFV, r0)
opset(AMOVVF, r0)
opset(AMOVFV, r0)
opset(AMOVVD, r0)
opset(AMOVDV, r0)
case AADD:
opset(ASGT, r0)
opset(ASGTU, r0)
opset(AADDU, r0)
opset(AADDV, r0)
opset(AADDVU, r0)
case AADDF:
opset(ADIVF, r0)
opset(ADIVD, r0)
opset(AMULF, r0)
opset(AMULD, r0)
opset(ASUBF, r0)
opset(ASUBD, r0)
opset(AADDD, r0)
case AAND:
opset(AOR, r0)
opset(AXOR, r0)
case ABEQ:
opset(ABNE, r0)
case ABLEZ:
opset(ABGEZ, r0)
opset(ABGEZAL, r0)
opset(ABLTZ, r0)
opset(ABLTZAL, r0)
opset(ABGTZ, r0)
case AMOVB:
opset(AMOVH, r0)
case AMOVBU:
opset(AMOVHU, r0)
case AMUL:
opset(AREM, r0)
opset(AREMU, r0)
opset(ADIVU, r0)
opset(AMULU, r0)
opset(ADIV, r0)
opset(ADIVV, r0)
opset(ADIVVU, r0)
opset(AMULV, r0)
opset(AMULVU, r0)
opset(AREMV, r0)
opset(AREMVU, r0)
case ASLL:
opset(ASRL, r0)
opset(ASRA, r0)
opset(ASLLV, r0)
//.........這裏部分代碼省略.........
示例11: span0
func span0(ctxt *obj.Link, cursym *obj.LSym) {
p := cursym.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
return
}
ctxt.Cursym = cursym
ctxt.Autosize = int32(p.To.Offset + 8)
if oprange[AOR&obj.AMask].start == nil {
buildop(ctxt)
}
c := int64(0)
p.Pc = c
var m int
var o *Optab
for p = p.Link; p != nil; p = p.Link {
ctxt.Curp = p
p.Pc = c
o = oplook(ctxt, p)
m = int(o.size)
if m == 0 {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
ctxt.Diag("zero-width instruction\n%v", p)
}
continue
}
c += int64(m)
}
cursym.Size = c
/*
* if any procedure is large enough to
* generate a large SBRA branch, then
* generate extra passes putting branches
* around jmps to fix. this is rare.
*/
bflag := 1
var otxt int64
var q *obj.Prog
for bflag != 0 {
if ctxt.Debugvlog != 0 {
fmt.Fprintf(ctxt.Bso, "%5.2f span1\n", obj.Cputime())
}
bflag = 0
c = 0
for p = cursym.Text.Link; p != nil; p = p.Link {
p.Pc = c
o = oplook(ctxt, p)
// very large conditional branches
if o.type_ == 6 && p.Pcond != nil {
otxt = p.Pcond.Pc - c
if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 {
q = ctxt.NewProg()
q.Link = p.Link
p.Link = q
q.As = AJMP
q.Lineno = p.Lineno
q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Pcond
p.Pcond = q
q = ctxt.NewProg()
q.Link = p.Link
p.Link = q
q.As = AJMP
q.Lineno = p.Lineno
q.To.Type = obj.TYPE_BRANCH
q.Pcond = q.Link.Link
addnop(ctxt, p.Link)
addnop(ctxt, p)
bflag = 1
}
}
m = int(o.size)
if m == 0 {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
ctxt.Diag("zero-width instruction\n%v", p)
}
continue
}
c += int64(m)
}
cursym.Size = c
}
c += -c & (FuncAlign - 1)
cursym.Size = c
/*
* lay out the code, emitting code and data relocations.
*/
//.........這裏部分代碼省略.........
示例12: opirr
//.........這裏部分代碼省略.........
case ABGTZ:
return SP(0, 7)
case ABGTZ + ALAST:
return SP(2, 7) /* likely */
case ABLEZ:
return SP(0, 6)
case ABLEZ + ALAST:
return SP(2, 6) /* likely */
case ABLTZ:
return SP(0, 1) | BCOND(0, 0)
case ABLTZ + ALAST:
return SP(0, 1) | BCOND(0, 2) /* likely */
case ABLTZAL:
return SP(0, 1) | BCOND(2, 0)
case ABLTZAL + ALAST:
return SP(0, 1) | BCOND(2, 2) /* likely */
case ABFPT:
return SP(2, 1) | (257 << 16)
case ABFPT + ALAST:
return SP(2, 1) | (259 << 16) /* likely */
case ABFPF:
return SP(2, 1) | (256 << 16)
case ABFPF + ALAST:
return SP(2, 1) | (258 << 16) /* likely */
case AMOVB,
AMOVBU:
return SP(5, 0)
case AMOVH,
AMOVHU:
return SP(5, 1)
case AMOVW,
AMOVWU:
return SP(5, 3)
case AMOVV:
return SP(7, 7)
case AMOVF:
return SP(7, 1)
case AMOVD:
return SP(7, 5)
case AMOVWL:
return SP(5, 2)
case AMOVWR:
return SP(5, 6)
case AMOVVL:
return SP(5, 4)
case AMOVVR:
return SP(5, 5)
case ABREAK:
return SP(5, 7)
case AMOVWL + ALAST:
return SP(4, 2)
case AMOVWR + ALAST:
return SP(4, 6)
case AMOVVL + ALAST:
return SP(3, 2)
case AMOVVR + ALAST:
return SP(3, 3)
case AMOVB + ALAST:
return SP(4, 0)
case AMOVBU + ALAST:
return SP(4, 4)
case AMOVH + ALAST:
return SP(4, 1)
case AMOVHU + ALAST:
return SP(4, 5)
case AMOVW + ALAST:
return SP(4, 3)
case AMOVWU + ALAST:
return SP(4, 7)
case AMOVV + ALAST:
return SP(6, 7)
case AMOVF + ALAST:
return SP(6, 1)
case AMOVD + ALAST:
return SP(6, 5)
case ASLLV:
return OP(7, 0)
case ASRLV:
return OP(7, 2)
case ASRAV:
return OP(7, 3)
case ASLLV + ALAST:
return OP(7, 4)
case ASRLV + ALAST:
return OP(7, 6)
case ASRAV + ALAST:
return OP(7, 7)
}
if a >= ALAST {
ctxt.Diag("bad irr opcode %v+ALAST", obj.Aconv(a-ALAST))
} else {
ctxt.Diag("bad irr opcode %v", obj.Aconv(a))
}
return 0
}
示例13: oprrr
//.........這裏部分代碼省略.........
case AMULVU:
return OP(3, 5)
case AJMP:
return OP(1, 0)
case AJAL:
return OP(1, 1)
case ABREAK:
return OP(1, 5)
case ASYSCALL:
return OP(1, 4)
case ATLBP:
return MMU(1, 0)
case ATLBR:
return MMU(0, 1)
case ATLBWI:
return MMU(0, 2)
case ATLBWR:
return MMU(0, 6)
case ARFE:
return MMU(2, 0)
case ADIVF:
return FPF(0, 3)
case ADIVD:
return FPD(0, 3)
case AMULF:
return FPF(0, 2)
case AMULD:
return FPD(0, 2)
case ASUBF:
return FPF(0, 1)
case ASUBD:
return FPD(0, 1)
case AADDF:
return FPF(0, 0)
case AADDD:
return FPD(0, 0)
case ATRUNCFV:
return FPF(1, 1)
case ATRUNCDV:
return FPD(1, 1)
case ATRUNCFW:
return FPF(1, 5)
case ATRUNCDW:
return FPD(1, 5)
case AMOVFV:
return FPF(4, 5)
case AMOVDV:
return FPD(4, 5)
case AMOVVF:
return FPV(4, 0)
case AMOVVD:
return FPV(4, 1)
case AMOVFW:
return FPF(4, 4)
case AMOVDW:
return FPD(4, 4)
case AMOVWF:
return FPW(4, 0)
case AMOVDF:
return FPD(4, 0)
case AMOVWD:
return FPW(4, 1)
case AMOVFD:
return FPF(4, 1)
case AABSF:
return FPF(0, 5)
case AABSD:
return FPD(0, 5)
case AMOVF:
return FPF(0, 6)
case AMOVD:
return FPD(0, 6)
case ANEGF:
return FPF(0, 7)
case ANEGD:
return FPD(0, 7)
case ACMPEQF:
return FPF(6, 2)
case ACMPEQD:
return FPD(6, 2)
case ACMPGTF:
return FPF(7, 4)
case ACMPGTD:
return FPD(7, 4)
case ACMPGEF:
return FPF(7, 6)
case ACMPGED:
return FPD(7, 6)
}
if a >= ALAST {
ctxt.Diag("bad rrr opcode %v+ALAST", obj.Aconv(a-ALAST))
} else {
ctxt.Diag("bad rrr opcode %v", obj.Aconv(a))
}
return 0
}
示例14: preprocess
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// TODO(minux): add morestack short-cuts with small fixed frame-size.
ctxt.Cursym = cursym
if cursym.Text == nil || cursym.Text.Link == nil {
return
}
p := cursym.Text
textstksiz := p.To.Offset
if textstksiz == -8 {
// Compatibility hack.
p.From3.Offset |= obj.NOFRAME
textstksiz = 0
}
if textstksiz%8 != 0 {
ctxt.Diag("frame size %d not a multiple of 8", textstksiz)
}
if p.From3.Offset&obj.NOFRAME != 0 {
if textstksiz != 0 {
ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
}
}
cursym.Args = p.To.Val.(int32)
cursym.Locals = int32(textstksiz)
/*
* find leaf subroutines
* strip NOPs
* expand RET
* expand BECOME pseudo
*/
if ctxt.Debugvlog != 0 {
fmt.Fprintf(ctxt.Bso, "%5.2f noops\n", obj.Cputime())
}
ctxt.Bso.Flush()
var q *obj.Prog
var q1 *obj.Prog
for p := cursym.Text; p != nil; p = p.Link {
switch p.As {
/* too hard, just leave alone */
case obj.ATEXT:
q = p
p.Mark |= LABEL | LEAF | SYNC
if p.Link != nil {
p.Link.Mark |= LABEL
}
case ANOR:
q = p
if p.To.Type == obj.TYPE_REG {
if p.To.Reg == REGZERO {
p.Mark |= LABEL | SYNC
}
}
case ALWAR,
ASTWCCC,
AECIWX,
AECOWX,
AEIEIO,
AICBI,
AISYNC,
ATLBIE,
ATLBIEL,
ASLBIA,
ASLBIE,
ASLBMFEE,
ASLBMFEV,
ASLBMTE,
ADCBF,
ADCBI,
ADCBST,
ADCBT,
ADCBTST,
ADCBZ,
ASYNC,
ATLBSYNC,
APTESYNC,
ATW,
AWORD,
ARFI,
ARFCI,
ARFID,
AHRFID:
q = p
p.Mark |= LABEL | SYNC
continue
case AMOVW, AMOVWZ, AMOVD:
q = p
if p.From.Reg >= REG_SPECIAL || p.To.Reg >= REG_SPECIAL {
p.Mark |= LABEL | SYNC
}
continue
case AFABS,
//.........這裏部分代碼省略.........