From: Rob Pike Date: Fri, 27 Feb 2015 21:50:26 +0000 (-0800) Subject: cmd/internal/obj: clean up handling of register list operand on ARM X-Git-Tag: go1.5beta1~1816 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0eeb5cf088bbfd21f500e132fc4bb9a149376246;p=gostls13.git cmd/internal/obj: clean up handling of register list operand on ARM ARM operands for MOVM have lists of registers: [R1,R2,R5-R8]. Handle them cleanly. It was TYPE_CONST with special handling, which meant operand printing didn't work right and the special handling was ugly. Add a new TYPE_REGLIST for this case and it all gets cleaner. Change-Id: I4a64f70fb9765e63cb636619a7a8553611bfe970 Reviewed-on: https://go-review.googlesource.com/6300 Run-TryBot: Rob Pike TryBot-Result: Gobot Gobot Reviewed-by: Russ Cox --- diff --git a/src/cmd/5a/a.y b/src/cmd/5a/a.y index 39fab8fa26..c1ca3beaa8 100644 --- a/src/cmd/5a/a.y +++ b/src/cmd/5a/a.y @@ -179,7 +179,7 @@ inst: var g obj.Addr g = nullgen; - g.Type = obj.TYPE_CONST; + g.Type = obj.TYPE_REGLIST; g.Offset = int64($6); outcode($1, $2, &$3, 0, &g); } @@ -188,7 +188,7 @@ inst: var g obj.Addr g = nullgen; - g.Type = obj.TYPE_CONST; + g.Type = obj.TYPE_REGLIST; g.Offset = int64($4); outcode($1, $2, &g, 0, &$7); } diff --git a/src/cmd/5a/y.go b/src/cmd/5a/y.go index 7c7de64b15..a79f61d316 100644 --- a/src/cmd/5a/y.go +++ b/src/cmd/5a/y.go @@ -785,7 +785,7 @@ yydefault: var g obj.Addr g = nullgen - g.Type = obj.TYPE_CONST + g.Type = obj.TYPE_REGLIST g.Offset = int64(yyDollar[6].lval) outcode(yyDollar[1].lval, yyDollar[2].lval, &yyDollar[3].addr, 0, &g) } @@ -796,7 +796,7 @@ yydefault: var g obj.Addr g = nullgen - g.Type = obj.TYPE_CONST + g.Type = obj.TYPE_REGLIST g.Offset = int64(yyDollar[4].lval) outcode(yyDollar[1].lval, yyDollar[2].lval, &g, 0, &yyDollar[7].addr) } diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go index e8d3cda489..fd0331eb2c 100644 --- a/src/cmd/asm/internal/asm/operand_test.go +++ b/src/cmd/asm/internal/asm/operand_test.go @@ -316,12 +316,11 @@ var armOperandTests = []operandTest{ {"R6", "R6"}, {"R7", "R7"}, {"R8", "R8"}, - // TODO: Fix Dconv to handle these. MOVM print shows the registers. - {"[R0,R1,g,R15]", "$33795"}, - {"[R0-R7]", "$255"}, - {"[R(0)-R(7)]", "$255"}, - {"[R0]", "$1"}, - {"[R1-R12]", "$8190"}, + {"[R0,R1,g,R15]", "[R0,R1,g,R15]"}, + {"[R0-R7]", "[R0,R1,R2,R3,R4,R5,R6,R7]"}, + {"[R(0)-R(7)]", "[R0,R1,R2,R3,R4,R5,R6,R7]"}, + {"[R0]", "[R0]"}, + {"[R1-R12]", "[R1,R2,R3,R4,R5,R6,R7,R8,R9,g,R11,R12]"}, {"armCAS64(SB)", "armCAS64(SB)"}, {"asmcgocall<>(SB)", "asmcgocall<>(SB)"}, {"c+28(FP)", "c+28(FP)"}, diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go index 9048cca984..27d311293f 100644 --- a/src/cmd/asm/internal/asm/parse.go +++ b/src/cmd/asm/internal/asm/parse.go @@ -714,7 +714,7 @@ func (p *Parser) registerList(a *obj.Addr) { p.get(',') } } - a.Type = obj.TYPE_CONST + a.Type = obj.TYPE_REGLIST a.Offset = int64(bits) } diff --git a/src/cmd/asm/internal/asm/testdata/arm.out b/src/cmd/asm/internal/asm/testdata/arm.out index 1c4c7e79f6..9e6f080069 100644 --- a/src/cmd/asm/internal/asm/testdata/arm.out +++ b/src/cmd/asm/internal/asm/testdata/arm.out @@ -28,10 +28,10 @@ 110 00028 (testdata/arm.s:110) CMP.S $1,R2, 111 00029 (testdata/arm.s:111) CMP.S R1<offset != 0 too. + // TODO(rsc): After fixing PINSRQ, check a->offset != 0 too. // TODO(rsc): After fixing SHRQ, check a->index != 0 too. case TYPE_REG: if a.Scale != 0 || a.Name != 0 || a.Sym != nil { @@ -134,7 +134,10 @@ func checkaddr(ctxt *Link, p *Prog, a *Addr) { case TYPE_REGREG2: return - // Expect sym and name to be set, nothing else. + case TYPE_REGLIST: + return + + // Expect sym and name to be set, nothing else. // Technically more is allowed, but this is only used for *name(SB). case TYPE_INDIR: if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name == 0 || a.Offset != 0 || a.Sym == nil || a.U.Bits != 0 { diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go index 4a7578b257..1fda2c32a6 100644 --- a/src/cmd/internal/obj/util.go +++ b/src/cmd/internal/obj/util.go @@ -362,6 +362,9 @@ func Dconv(p *Prog, a *Addr) string { case TYPE_REGREG2: str = fmt.Sprintf("%v, %v", Rconv(int(a.Reg)), Rconv(int(a.Offset))) + + case TYPE_REGLIST: + str = regListConv(int(a.Offset)) } return str @@ -438,6 +441,8 @@ const ( RBaseARM = 3 * 1024 RBasePPC64 = 4 * 1024 // The next free base is 8*1024 (PPC64 has many registers). + // Alternatively, the next architecture, with an ordinary + // number of registers, could go under PPC64. ) // RegisterRegister binds a pretty-printer (Rconv) for register @@ -459,3 +464,26 @@ func Rconv(reg int) string { } return fmt.Sprintf("R???%d", reg) } + +func regListConv(list int) string { + str := "" + + for i := 0; i < 16; i++ { // TODO: 16 is ARM-specific. + if list&(1<