本文整理匯總了Golang中cmd/internal/obj.Rconv函數的典型用法代碼示例。如果您正苦於以下問題:Golang Rconv函數的具體用法?Golang Rconv怎麽用?Golang Rconv使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了Rconv函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: gclean
func gclean() {
for _, r := range Thearch.ReservedRegs {
reg[r-Thearch.REGMIN]--
}
for r := Thearch.REGMIN; r <= Thearch.REGMAX; r++ {
n := reg[r-Thearch.REGMIN]
if n != 0 {
if Debug['v'] != 0 {
Regdump()
}
Yyerror("reg %v left allocated", obj.Rconv(r))
}
}
for r := Thearch.FREGMIN; r <= Thearch.FREGMAX; r++ {
n := reg[r-Thearch.REGMIN]
if n != 0 {
if Debug['v'] != 0 {
Regdump()
}
Yyerror("reg %v left allocated", obj.Rconv(r))
}
}
}
示例2: archPPC64
func archPPC64() *Arch {
register := make(map[string]int16)
// Create maps for easy lookup of instruction names etc.
// Note that there is no list of names as there is for x86.
for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ {
register[obj.Rconv(i)] = int16(i)
}
register["CR"] = ppc64.REG_CR
register["XER"] = ppc64.REG_XER
register["LR"] = ppc64.REG_LR
register["CTR"] = ppc64.REG_CTR
register["FPSCR"] = ppc64.REG_FPSCR
register["MSR"] = ppc64.REG_MSR
// Pseudo-registers.
register["SB"] = RSB
register["FP"] = RFP
register["PC"] = RPC
// Avoid unintentionally clobbering g using R30.
delete(register, "R30")
register["g"] = ppc64.REG_R30
registerPrefix := map[string]bool{
"CR": true,
"F": true,
"R": true,
"SPR": true,
}
instructions := make(map[string]int)
for i, s := range obj.Anames {
instructions[s] = i
}
for i, s := range ppc64.Anames {
if i >= obj.A_ARCHSPECIFIC {
instructions[s] = i + obj.ABasePPC64
}
}
// Annoying aliases.
instructions["BR"] = ppc64.ABR
instructions["BL"] = ppc64.ABL
instructions["RETURN"] = ppc64.ARETURN
return &Arch{
LinkArch: &ppc64.Linkppc64,
Instructions: instructions,
Register: register,
RegisterPrefix: registerPrefix,
RegisterNumber: ppc64RegisterNumber,
IsJump: jumpPPC64,
}
}
示例3: archMips64
func archMips64() *Arch {
register := make(map[string]int16)
// Create maps for easy lookup of instruction names etc.
// Note that there is no list of names as there is for x86.
for i := mips.REG_R0; i <= mips.REG_R31; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := mips.REG_F0; i <= mips.REG_F31; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := mips.REG_M0; i <= mips.REG_M31; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
register[obj.Rconv(i)] = int16(i)
}
register["HI"] = mips.REG_HI
register["LO"] = mips.REG_LO
// Pseudo-registers.
register["SB"] = RSB
register["FP"] = RFP
register["PC"] = RPC
// Avoid unintentionally clobbering g using R30.
delete(register, "R30")
register["g"] = mips.REG_R30
// Avoid unintentionally clobbering RSB using R28.
delete(register, "R28")
register["RSB"] = mips.REG_R28
registerPrefix := map[string]bool{
"F": true,
"FCR": true,
"M": true,
"R": true,
}
instructions := make(map[string]obj.As)
for i, s := range obj.Anames {
instructions[s] = obj.As(i)
}
for i, s := range mips.Anames {
if obj.As(i) >= obj.A_ARCHSPECIFIC {
instructions[s] = obj.As(i) + obj.ABaseMIPS64
}
}
// Annoying alias.
instructions["JAL"] = mips.AJAL
return &Arch{
LinkArch: &mips.Linkmips64,
Instructions: instructions,
Register: register,
RegisterPrefix: registerPrefix,
RegisterNumber: mipsRegisterNumber,
IsJump: jumpMIPS64,
}
}
示例4: archS390x
func archS390x() *Arch {
register := make(map[string]int16)
// Create maps for easy lookup of instruction names etc.
// Note that there is no list of names as there is for x86.
for i := s390x.REG_R0; i <= s390x.REG_R15; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := s390x.REG_F0; i <= s390x.REG_F15; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := s390x.REG_V0; i <= s390x.REG_V31; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ {
register[obj.Rconv(i)] = int16(i)
}
register["LR"] = s390x.REG_LR
// Pseudo-registers.
register["SB"] = RSB
register["FP"] = RFP
register["PC"] = RPC
// Avoid unintentionally clobbering g using R13.
delete(register, "R13")
register["g"] = s390x.REG_R13
registerPrefix := map[string]bool{
"AR": true,
"F": true,
"R": true,
}
instructions := make(map[string]obj.As)
for i, s := range obj.Anames {
instructions[s] = obj.As(i)
}
for i, s := range s390x.Anames {
if obj.As(i) >= obj.A_ARCHSPECIFIC {
instructions[s] = obj.As(i) + obj.ABaseS390X
}
}
// Annoying aliases.
instructions["BR"] = s390x.ABR
instructions["BL"] = s390x.ABL
return &Arch{
LinkArch: &s390x.Links390x,
Instructions: instructions,
Register: register,
RegisterPrefix: registerPrefix,
RegisterNumber: s390xRegisterNumber,
IsJump: jumpS390x,
}
}
示例5: gclean
func gclean() {
for i := 0; i < len(resvd); i++ {
reg[resvd[i]]--
}
for i := x86.REG_AX; i <= x86.REG_DI; i++ {
if reg[i] != 0 {
gc.Yyerror("reg %v left allocated at %x", obj.Rconv(i), regpc[i])
}
}
for i := x86.REG_X0; i <= x86.REG_X7; i++ {
if reg[i] != 0 {
gc.Yyerror("reg %v left allocated\n", obj.Rconv(i))
}
}
}
示例6: Regdump
func Regdump() {
if Debug['v'] == 0 {
fmt.Printf("run compiler with -v for register allocation sites\n")
return
}
dump := func(r int) {
stk := regstk[r-Thearch.REGMIN]
if len(stk) == 0 {
return
}
fmt.Printf("reg %v allocated at:\n", obj.Rconv(r))
fmt.Printf("\t%s\n", strings.Replace(strings.TrimSpace(string(stk)), "\n", "\n\t", -1))
}
for r := Thearch.REGMIN; r <= Thearch.REGMAX; r++ {
if reg[r-Thearch.REGMIN] != 0 {
dump(r)
}
}
for r := Thearch.FREGMIN; r <= Thearch.FREGMAX; r++ {
if reg[r-Thearch.REGMIN] == 0 {
dump(r)
}
}
}
示例7: archArm
func archArm() *Arch {
register := make(map[string]int16)
// Create maps for easy lookup of instruction names etc.
// Note that there is no list of names as there is for x86.
for i := arm.REG_R0; i < arm.REG_SPSR; i++ {
register[obj.Rconv(i)] = int16(i)
}
// Avoid unintentionally clobbering g using R10.
delete(register, "R10")
register["g"] = arm.REG_R10
for i := 0; i < 16; i++ {
register[fmt.Sprintf("C%d", i)] = int16(i)
}
// Pseudo-registers.
register["SB"] = RSB
register["FP"] = RFP
register["PC"] = RPC
register["SP"] = RSP
registerPrefix := map[string]bool{
"F": true,
"R": true,
}
instructions := make(map[string]int)
for i, s := range obj.Anames {
instructions[s] = i
}
for i, s := range arm.Anames {
if i >= obj.A_ARCHSPECIFIC {
instructions[s] = i + obj.ABaseARM
}
}
// Annoying aliases.
instructions["B"] = obj.AJMP
instructions["BL"] = obj.ACALL
// MCR differs from MRC by the way fields of the word are encoded.
// (Details in arm.go). Here we add the instruction so parse will find
// it, but give it an opcode number known only to us.
instructions["MCR"] = aMCR
return &Arch{
LinkArch: &arm.Linkarm,
Instructions: instructions,
Register: register,
RegisterPrefix: registerPrefix,
RegisterNumber: armRegisterNumber,
IsJump: jumpArm,
}
}
示例8: copyu
// If s==nil, copyu returns the set/use of v in p; otherwise, it
// modifies p to replace reads of v with reads of s and returns 0 for
// success or non-zero for failure.
//
// If s==nil, copy returns one of the following values:
// 1 if v only used
// 2 if v is set and used in one address (read-alter-rewrite;
// can't substitute)
// 3 if v is only set
// 4 if v is set in one address and used in another (so addresses
// can be rewritten independently)
// 0 otherwise (not touched)
func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.From3Type() != obj.TYPE_NONE {
// 7g never generates a from3
fmt.Printf("copyu: from3 (%v) not implemented\n", gc.Ctxt.Dconv(p.From3))
}
if p.RegTo2 != obj.REG_NONE {
// 7g never generates a to2
fmt.Printf("copyu: RegTo2 (%v) not implemented\n", obj.Rconv(int(p.RegTo2)))
}
switch p.As {
default:
fmt.Printf("copyu: can't find %v\n", obj.Aconv(p.As))
return 2
case obj.ANOP, /* read p->from, write p->to */
arm64.ANEG,
arm64.AFNEGD,
arm64.AFNEGS,
arm64.AFSQRTD,
arm64.AFCVTZSD,
arm64.AFCVTZSS,
arm64.AFCVTZSDW,
arm64.AFCVTZSSW,
arm64.AFCVTZUD,
arm64.AFCVTZUS,
arm64.AFCVTZUDW,
arm64.AFCVTZUSW,
arm64.AFCVTSD,
arm64.AFCVTDS,
arm64.ASCVTFD,
arm64.ASCVTFS,
arm64.ASCVTFWD,
arm64.ASCVTFWS,
arm64.AUCVTFD,
arm64.AUCVTFS,
arm64.AUCVTFWD,
arm64.AUCVTFWS,
arm64.AMOVB,
arm64.AMOVBU,
arm64.AMOVH,
arm64.AMOVHU,
arm64.AMOVW,
arm64.AMOVWU,
arm64.AMOVD,
arm64.AFMOVS,
arm64.AFMOVD:
if p.Scond == 0 {
if s != nil {
if copysub(&p.From, v, s, true) {
return 1
}
// Update only indirect uses of v in p->to
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, true) {
return 1
}
}
return 0
}
if copyas(&p.To, v) {
// Fix up implicit from
if p.From.Type == obj.TYPE_NONE {
p.From = p.To
}
if copyau(&p.From, v) {
return 4
}
return 3
}
if copyau(&p.From, v) {
return 1
}
if copyau(&p.To, v) {
// p->to only indirectly uses v
return 1
}
return 0
}
/* rar p->from, write p->to or read p->from, rar p->to */
if p.From.Type == obj.TYPE_MEM {
if copyas(&p.From, v) {
// No s!=nil check; need to fail
//.........這裏部分代碼省略.........
示例9: anyregalloc
//.........這裏部分代碼省略.........
}
func regfree(n *gc.Node) {
if false && gc.Debug['r'] != 0 {
fixfree := 0
for i := REGALLOC_R0; i <= REGALLOC_RMAX; i++ {
if reg[i] == 0 {
fixfree++
}
}
floatfree := 0
for i := REGALLOC_F0; i <= REGALLOC_FMAX; i++ {
if reg[i] == 0 {
floatfree++
}
}
fmt.Printf("regalloc fix %d float %d\n", fixfree, floatfree)
}
if n.Op == gc.ONAME {
return
}
if n.Op != gc.OREGISTER && n.Op != gc.OINDREG {
gc.Fatal("regfree: not a register")
}
i := int(n.Val.U.Reg)
if i == arm.REGSP {
return
}
if i < 0 || i >= len(reg) || i >= len(regpc) {
gc.Fatal("regfree: reg out of range")
}
if reg[i] <= 0 {
gc.Fatal("regfree: reg %v not allocated", obj.Rconv(i))
}
reg[i]--
if reg[i] == 0 {
regpc[i] = 0
}
}
/*
* return constant i node.
* overwritten by next call, but useful in calls to gins.
*/
var ncon_n gc.Node
func ncon(i uint32) *gc.Node {
if ncon_n.Type == nil {
gc.Nodconst(&ncon_n, gc.Types[gc.TUINT32], 0)
}
gc.Mpmovecfix(ncon_n.Val.U.Xval, int64(i))
return &ncon_n
}
var sclean [10]gc.Node
var nsclean int
/*
* n is a 64-bit value. fill in lo and hi to refer to its 32-bit halves.
*/
func split64(n *gc.Node, lo *gc.Node, hi *gc.Node) {
if !gc.Is64(n.Type) {
gc.Fatal("split64 %v", gc.Tconv(n.Type, 0))
示例10: clearfat
func clearfat(nl *gc.Node) {
/* clear a fat object */
if gc.Debug['g'] != 0 {
fmt.Printf("clearfat %v (%v, size: %d)\n", nl, nl.Type, nl.Type.Width)
}
w := uint64(uint64(nl.Type.Width))
// Avoid taking the address for simple enough types.
if gc.Componentgen(nil, nl) {
return
}
c := uint64(w % 8) // bytes
q := uint64(w / 8) // dwords
if gc.Reginuse(ppc64.REGRT1) {
gc.Fatal("%v in use during clearfat", obj.Rconv(ppc64.REGRT1))
}
var r0 gc.Node
gc.Nodreg(&r0, gc.Types[gc.TUINT64], ppc64.REGZERO)
var dst gc.Node
gc.Nodreg(&dst, gc.Types[gc.Tptr], ppc64.REGRT1)
gc.Regrealloc(&dst)
gc.Agen(nl, &dst)
var boff uint64
if q > 128 {
p := gins(ppc64.ASUB, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = 8
var end gc.Node
gc.Regalloc(&end, gc.Types[gc.Tptr], nil)
p = gins(ppc64.AMOVD, &dst, &end)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = int64(q * 8)
p = gins(ppc64.AMOVDU, &r0, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = 8
pl := (*obj.Prog)(p)
p = gins(ppc64.ACMP, &dst, &end)
gc.Patch(gc.Gbranch(ppc64.ABNE, nil, 0), pl)
gc.Regfree(&end)
// The loop leaves R3 on the last zeroed dword
boff = 8
} else if q >= 4 {
p := gins(ppc64.ASUB, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = 8
f := (*gc.Node)(gc.Sysfunc("duffzero"))
p = gins(obj.ADUFFZERO, nil, f)
gc.Afunclit(&p.To, f)
// 4 and 128 = magic constants: see ../../runtime/asm_ppc64x.s
p.To.Offset = int64(4 * (128 - q))
// duffzero leaves R3 on the last zeroed dword
boff = 8
} else {
var p *obj.Prog
for t := uint64(0); t < q; t++ {
p = gins(ppc64.AMOVD, &r0, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(8 * t)
}
boff = 8 * q
}
var p *obj.Prog
for t := uint64(0); t < c; t++ {
p = gins(ppc64.AMOVB, &r0, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(t + boff)
}
gc.Regfree(&dst)
}
示例11: nodedump
func nodedump(n *Node, flag int) string {
if n == nil {
return ""
}
recur := flag&obj.FmtShort == 0 /*untyped*/
var buf bytes.Buffer
if recur {
indent(&buf)
if dumpdepth > 10 {
buf.WriteString("...")
return buf.String()
}
if n.Ninit != nil {
fmt.Fprintf(&buf, "%v-init%v", Oconv(int(n.Op), 0), Hconv(n.Ninit, 0))
indent(&buf)
}
}
switch n.Op {
default:
fmt.Fprintf(&buf, "%v%v", Oconv(int(n.Op), 0), Jconv(n, 0))
case OREGISTER,
OINDREG:
fmt.Fprintf(&buf, "%v-%v%v", Oconv(int(n.Op), 0), obj.Rconv(int(n.Val.U.Reg)), Jconv(n, 0))
case OLITERAL:
fmt.Fprintf(&buf, "%v-%v%v", Oconv(int(n.Op), 0), Vconv(&n.Val, 0), Jconv(n, 0))
case ONAME,
ONONAME:
if n.Sym != nil {
fmt.Fprintf(&buf, "%v-%v%v", Oconv(int(n.Op), 0), Sconv(n.Sym, 0), Jconv(n, 0))
} else {
fmt.Fprintf(&buf, "%v%v", Oconv(int(n.Op), 0), Jconv(n, 0))
}
if recur && n.Type == nil && n.Ntype != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-ntype%v", Oconv(int(n.Op), 0), Nconv(n.Ntype, 0))
}
case OASOP:
fmt.Fprintf(&buf, "%v-%v%v", Oconv(int(n.Op), 0), Oconv(int(n.Etype), 0), Jconv(n, 0))
case OTYPE:
fmt.Fprintf(&buf, "%v %v%v type=%v", Oconv(int(n.Op), 0), Sconv(n.Sym, 0), Jconv(n, 0), Tconv(n.Type, 0))
if recur && n.Type == nil && n.Ntype != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-ntype%v", Oconv(int(n.Op), 0), Nconv(n.Ntype, 0))
}
}
if n.Sym != nil && n.Op != ONAME {
fmt.Fprintf(&buf, " %v G%d", Sconv(n.Sym, 0), n.Vargen)
}
if n.Type != nil {
fmt.Fprintf(&buf, " %v", Tconv(n.Type, 0))
}
if recur {
if n.Left != nil {
buf.WriteString(Nconv(n.Left, 0))
}
if n.Right != nil {
buf.WriteString(Nconv(n.Right, 0))
}
if n.List != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-list%v", Oconv(int(n.Op), 0), Hconv(n.List, 0))
}
if n.Rlist != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-rlist%v", Oconv(int(n.Op), 0), Hconv(n.Rlist, 0))
}
if n.Ntest != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-test%v", Oconv(int(n.Op), 0), Nconv(n.Ntest, 0))
}
if n.Nbody != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-body%v", Oconv(int(n.Op), 0), Hconv(n.Nbody, 0))
}
if n.Nelse != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-else%v", Oconv(int(n.Op), 0), Hconv(n.Nelse, 0))
}
if n.Nincr != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-incr%v", Oconv(int(n.Op), 0), Nconv(n.Nincr, 0))
}
}
//.........這裏部分代碼省略.........
示例12: exprfmt
func exprfmt(n *Node, prec int) string {
for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) {
n = n.Left
}
if n == nil {
return "<N>"
}
nprec := opprec[n.Op]
if n.Op == OTYPE && n.Sym != nil {
nprec = 8
}
if prec > nprec {
return fmt.Sprintf("(%v)", Nconv(n, 0))
}
switch n.Op {
case OPAREN:
return fmt.Sprintf("(%v)", Nconv(n.Left, 0))
case ODDDARG:
return "... argument"
case OREGISTER:
return obj.Rconv(int(n.Val.U.Reg))
case OLITERAL: // this is a bit of a mess
if fmtmode == FErr {
if n.Orig != nil && n.Orig != n {
return exprfmt(n.Orig, prec)
}
if n.Sym != nil {
return Sconv(n.Sym, 0)
}
}
if n.Val.Ctype == CTNIL && n.Orig != nil && n.Orig != n {
return exprfmt(n.Orig, prec)
}
if n.Type != nil && n.Type != Types[n.Type.Etype] && n.Type != idealbool && n.Type != idealstring {
// Need parens when type begins with what might
// be misinterpreted as a unary operator: * or <-.
if Isptr[n.Type.Etype] || (n.Type.Etype == TCHAN && n.Type.Chan == Crecv) {
return fmt.Sprintf("(%v)(%v)", Tconv(n.Type, 0), Vconv(&n.Val, 0))
} else {
return fmt.Sprintf("%v(%v)", Tconv(n.Type, 0), Vconv(&n.Val, 0))
}
}
return Vconv(&n.Val, 0)
// Special case: name used as local variable in export.
// _ becomes ~b%d internally; print as _ for export
case ONAME:
if fmtmode == FExp && n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
return "_"
}
if fmtmode == FExp && n.Sym != nil && !isblank(n) && n.Vargen > 0 {
return fmt.Sprintf("%v·%d", Sconv(n.Sym, 0), n.Vargen)
}
// Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
// but for export, this should be rendered as (*pkg.T).meth.
// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
if fmtmode == FExp && n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME {
if Isptr[n.Left.Type.Etype] {
return fmt.Sprintf("(%v).%v", Tconv(n.Left.Type, 0), Sconv(n.Right.Sym, obj.FmtShort|obj.FmtByte))
} else {
return fmt.Sprintf("%v.%v", Tconv(n.Left.Type, 0), Sconv(n.Right.Sym, obj.FmtShort|obj.FmtByte))
}
}
fallthrough
//fallthrough
case OPACK,
ONONAME:
return Sconv(n.Sym, 0)
case OTYPE:
if n.Type == nil && n.Sym != nil {
return Sconv(n.Sym, 0)
}
return Tconv(n.Type, 0)
case OTARRAY:
if n.Left != nil {
return fmt.Sprintf("[]%v", Nconv(n.Left, 0))
}
var f string
f += fmt.Sprintf("[]%v", Nconv(n.Right, 0))
return f // happens before typecheck
case OTMAP:
return fmt.Sprintf("map[%v]%v", Nconv(n.Left, 0), Nconv(n.Right, 0))
case OTCHAN:
switch n.Etype {
case Crecv:
return fmt.Sprintf("<-chan %v", Nconv(n.Left, 0))
//.........這裏部分代碼省略.........
示例13: regopt
//.........這裏部分代碼省略.........
}
if nregion >= MaxRgn {
if Debug['v'] != 0 {
Warn("too many regions: %d\n", nregion)
}
nregion = MaxRgn
}
sort.Sort(rcmp(region[:nregion]))
if Debug['R'] != 0 && Debug['v'] != 0 {
Dumpit("pass5", firstf, 1)
}
// pass 6
// determine used registers (paint2)
// replace code (paint3)
if Debug['R'] != 0 && Debug['v'] != 0 {
fmt.Printf("\nregisterizing\n")
}
var usedreg uint64
var vreg uint64
for i := 0; i < nregion; i++ {
rgp = ®ion[i]
if Debug['R'] != 0 && Debug['v'] != 0 {
fmt.Printf("region %d: cost %d varno %d enter %d\n", i, rgp.cost, rgp.varno, rgp.enter.Prog.Pc)
}
bit = blsh(uint(rgp.varno))
usedreg = paint2(rgp.enter, int(rgp.varno), 0)
vreg = allreg(usedreg, rgp)
if rgp.regno != 0 {
if Debug['R'] != 0 && Debug['v'] != 0 {
v := &vars[rgp.varno]
fmt.Printf("registerize %v+%d (bit=%2d et=%v) in %v usedreg=%#x vreg=%#x\n", v.node, v.offset, rgp.varno, Econv(v.etype), obj.Rconv(int(rgp.regno)), usedreg, vreg)
}
paint3(rgp.enter, int(rgp.varno), vreg, int(rgp.regno))
}
}
// free aux structures. peep allocates new ones.
for i := 0; i < nvar; i++ {
vars[i].node.SetOpt(nil)
}
Flowend(g)
firstf = nil
if Debug['R'] != 0 && Debug['v'] != 0 {
// Rebuild flow graph, since we inserted instructions
g := Flowstart(firstp, nil)
firstf = g.Start
Dumpit("pass6", firstf, 0)
Flowend(g)
firstf = nil
}
// pass 7
// peep-hole on basic block
if Debug['R'] == 0 || Debug['P'] != 0 {
Thearch.Peep(firstp)
}
// eliminate nops
for p := firstp; p != nil; p = p.Link {
for p.Link != nil && p.Link.As == obj.ANOP {
p.Link = p.Link.Link
示例14: clearfat
func clearfat(nl *gc.Node) {
/* clear a fat object */
if gc.Debug['g'] != 0 {
fmt.Printf("clearfat %v (%v, size: %d)\n", nl, nl.Type, nl.Type.Width)
}
w := uint64(nl.Type.Width)
// Avoid taking the address for simple enough types.
if gc.Componentgen(nil, nl) {
return
}
c := w % 8 // bytes
q := w / 8 // dwords
if gc.Reginuse(mips.REGRT1) {
gc.Fatalf("%v in use during clearfat", obj.Rconv(mips.REGRT1))
}
var r0 gc.Node
gc.Nodreg(&r0, gc.Types[gc.TUINT64], mips.REGZERO)
var dst gc.Node
gc.Nodreg(&dst, gc.Types[gc.Tptr], mips.REGRT1)
gc.Regrealloc(&dst)
gc.Agen(nl, &dst)
var boff uint64
if q > 128 {
p := gins(mips.ASUBV, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = 8
var end gc.Node
gc.Regalloc(&end, gc.Types[gc.Tptr], nil)
p = gins(mips.AMOVV, &dst, &end)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = int64(q * 8)
p = gins(mips.AMOVV, &r0, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = 8
pl := p
p = gins(mips.AADDV, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = 8
gc.Patch(ginsbranch(mips.ABNE, nil, &dst, &end, 0), pl)
gc.Regfree(&end)
// The loop leaves R1 on the last zeroed dword
boff = 8
// TODO(dfc): https://golang.org/issue/12108
// If DUFFZERO is used inside a tail call (see genwrapper) it will
// overwrite the link register.
} else if false && q >= 4 {
p := gins(mips.ASUBV, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = 8
f := gc.Sysfunc("duffzero")
p = gins(obj.ADUFFZERO, nil, f)
gc.Afunclit(&p.To, f)
// 8 and 128 = magic constants: see ../../runtime/asm_mips64x.s
p.To.Offset = int64(8 * (128 - q))
// duffzero leaves R1 on the last zeroed dword
boff = 8
} else {
var p *obj.Prog
for t := uint64(0); t < q; t++ {
p = gins(mips.AMOVV, &r0, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(8 * t)
}
boff = 8 * q
}
var p *obj.Prog
for t := uint64(0); t < c; t++ {
p = gins(mips.AMOVB, &r0, &dst)
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(t + boff)
}
gc.Regfree(&dst)
}
示例15: exprfmt
func (n *Node) exprfmt(s fmt.State, prec int) {
for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) {
n = n.Left
}
if n == nil {
fmt.Fprint(s, "<N>")
return
}
nprec := opprec[n.Op]
if n.Op == OTYPE && n.Sym != nil {
nprec = 8
}
if prec > nprec {
fmt.Fprintf(s, "(%v)", n)
return
}
switch n.Op {
case OPAREN:
fmt.Fprintf(s, "(%v)", n.Left)
case ODDDARG:
fmt.Fprint(s, "... argument")
case OREGISTER:
fmt.Fprint(s, obj.Rconv(int(n.Reg)))
case OLITERAL: // this is a bit of a mess
if fmtmode == FErr {
if n.Orig != nil && n.Orig != n {
n.Orig.exprfmt(s, prec)
return
}
if n.Sym != nil {
fmt.Fprint(s, n.Sym.String())
return
}
}
if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n {
n.Orig.exprfmt(s, prec)
return
}
if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != idealbool && n.Type != idealstring {
// Need parens when type begins with what might
// be misinterpreted as a unary operator: * or <-.
if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == Crecv) {
fmt.Fprintf(s, "(%v)(%v)", n.Type, n.Val())
return
} else {
fmt.Fprintf(s, "%v(%v)", n.Type, n.Val())
return
}
}
fmt.Fprintf(s, "%v", n.Val())
// Special case: name used as local variable in export.
// _ becomes ~b%d internally; print as _ for export
case ONAME:
if fmtmode == FErr && n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
fmt.Fprint(s, "_")
return
}
fallthrough
case OPACK, ONONAME:
fmt.Fprint(s, n.Sym.String())
case OTYPE:
if n.Type == nil && n.Sym != nil {
fmt.Fprint(s, n.Sym.String())
return
}
fmt.Fprintf(s, "%v", n.Type)
case OTARRAY:
if n.Left != nil {
fmt.Fprintf(s, "[]%v", n.Left)
return
}
fmt.Fprintf(s, "[]%v", n.Right) // happens before typecheck
case OTMAP:
fmt.Fprintf(s, "map[%v]%v", n.Left, n.Right)
case OTCHAN:
switch ChanDir(n.Etype) {
case Crecv:
fmt.Fprintf(s, "<-chan %v", n.Left)
case Csend:
fmt.Fprintf(s, "chan<- %v", n.Left)
default:
if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && ChanDir(n.Left.Etype) == Crecv {
fmt.Fprintf(s, "chan (%v)", n.Left)
} else {
fmt.Fprintf(s, "chan %v", n.Left)
//.........這裏部分代碼省略.........