mirror of
https://github.com/golang/go.git
synced 2025-05-18 05:44:35 +00:00
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256. - Brings in new, more regular Prog, Addr definitions - Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion. - Update objwriter for change in TEXT size encoding. - Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand). - Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm. They need to be updated for the changes. - Reenable verifyAsm in cmd/go. - Reenable GOOBJ=2 mode by default in liblink. All architectures build successfully again. Change-Id: I2c845c5d365aa484b570476898171bee657b626d Reviewed-on: https://go-review.googlesource.com/3963 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
8db173b85e
commit
1fc330d8fe
@ -1,3 +1,5 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
@ -1678,7 +1678,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool,
|
|||||||
// verifyAsm specifies whether to check the assemblers written in Go
|
// verifyAsm specifies whether to check the assemblers written in Go
|
||||||
// against the assemblers written in C. If set, asm will run both (say) 6a and new6a
|
// against the assemblers written in C. If set, asm will run both (say) 6a and new6a
|
||||||
// and fail if the two produce different output files.
|
// and fail if the two produce different output files.
|
||||||
const verifyAsm = false
|
const verifyAsm = true
|
||||||
|
|
||||||
func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
|
func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
|
||||||
// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
|
// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
|
||||||
@ -1691,8 +1691,8 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
|
|||||||
if verifyAsm {
|
if verifyAsm {
|
||||||
newArgs := make([]interface{}, len(args))
|
newArgs := make([]interface{}, len(args))
|
||||||
copy(newArgs, args)
|
copy(newArgs, args)
|
||||||
newArgs[0] = tool("new" + archChar + "a")
|
newArgs[1] = tool("new" + archChar + "a")
|
||||||
newArgs[2] = ofile + ".new" // x.6 becomes x.6.new
|
newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
|
||||||
if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
|
if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1705,7 +1705,7 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !bytes.Equal(data1, data2) {
|
if !bytes.Equal(data1, data2) {
|
||||||
return fmt.Errorf("%sa and n%sa produced different output files:\n%s\n%s", archChar, archChar, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " "))
|
return fmt.Errorf("%sa and new%sa produced different output files:\n%s\n%s", archChar, archChar, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -30,17 +30,7 @@
|
|||||||
|
|
||||||
package arm
|
package arm
|
||||||
|
|
||||||
// list[5689].c
|
import "cmd/internal/obj"
|
||||||
|
|
||||||
// obj.c
|
|
||||||
|
|
||||||
// objfile.c
|
|
||||||
|
|
||||||
// pass.c
|
|
||||||
|
|
||||||
// pcln.c
|
|
||||||
|
|
||||||
// sym.c
|
|
||||||
|
|
||||||
// TODO(ality): remove this workaround.
|
// TODO(ality): remove this workaround.
|
||||||
// It's here because Pconv in liblink/list?.c references %L.
|
// It's here because Pconv in liblink/list?.c references %L.
|
||||||
@ -57,18 +47,54 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
REGRET = 0
|
REG_R0 = 32 + iota
|
||||||
REGEXT = 10
|
REG_R1
|
||||||
|
REG_R2
|
||||||
|
REG_R3
|
||||||
|
REG_R4
|
||||||
|
REG_R5
|
||||||
|
REG_R6
|
||||||
|
REG_R7
|
||||||
|
REG_R8
|
||||||
|
REG_R9
|
||||||
|
REG_R10
|
||||||
|
REG_R11
|
||||||
|
REG_R12
|
||||||
|
REG_R13
|
||||||
|
REG_R14
|
||||||
|
REG_R15
|
||||||
|
REG_F0
|
||||||
|
REG_F1
|
||||||
|
REG_F2
|
||||||
|
REG_F3
|
||||||
|
REG_F4
|
||||||
|
REG_F5
|
||||||
|
REG_F6
|
||||||
|
REG_F7
|
||||||
|
REG_F8
|
||||||
|
REG_F9
|
||||||
|
REG_F10
|
||||||
|
REG_F11
|
||||||
|
REG_F12
|
||||||
|
REG_F13
|
||||||
|
REG_F14
|
||||||
|
REG_F15
|
||||||
|
REG_FPSR
|
||||||
|
REG_FPCR
|
||||||
|
REG_CPSR
|
||||||
|
REG_SPSR
|
||||||
|
REGRET = REG_R0
|
||||||
|
REGEXT = REG_R10
|
||||||
REGG = REGEXT - 0
|
REGG = REGEXT - 0
|
||||||
REGM = REGEXT - 1
|
REGM = REGEXT - 1
|
||||||
REGTMP = 11
|
REGTMP = REG_R11
|
||||||
REGSP = 13
|
REGSP = REG_R13
|
||||||
REGLINK = 14
|
REGLINK = REG_R14
|
||||||
REGPC = 15
|
REGPC = REG_R15
|
||||||
NFREG = 16
|
NFREG = 16
|
||||||
FREGRET = 0
|
FREGRET = REG_F0
|
||||||
FREGEXT = 7
|
FREGEXT = REG_F7
|
||||||
FREGTMP = 15
|
FREGTMP = REG_F15
|
||||||
)
|
)
|
||||||
|
|
||||||
/* compiler allocates register variables F0 up */
|
/* compiler allocates register variables F0 up */
|
||||||
@ -110,13 +136,13 @@ const (
|
|||||||
C_SP
|
C_SP
|
||||||
C_HREG
|
C_HREG
|
||||||
C_ADDR
|
C_ADDR
|
||||||
|
C_TEXTSIZE
|
||||||
C_GOK
|
C_GOK
|
||||||
C_NCLASS
|
C_NCLASS
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AXXX = iota
|
AAND = obj.A_ARCHSPECIFIC + iota
|
||||||
AAND
|
|
||||||
AEOR
|
AEOR
|
||||||
ASUB
|
ASUB
|
||||||
ARSB
|
ARSB
|
||||||
@ -131,8 +157,6 @@ const (
|
|||||||
AORR
|
AORR
|
||||||
ABIC
|
ABIC
|
||||||
AMVN
|
AMVN
|
||||||
AB
|
|
||||||
ABL
|
|
||||||
ABEQ
|
ABEQ
|
||||||
ABNE
|
ABNE
|
||||||
ABCS
|
ABCS
|
||||||
@ -190,23 +214,12 @@ const (
|
|||||||
AMOVM
|
AMOVM
|
||||||
ASWPBU
|
ASWPBU
|
||||||
ASWPW
|
ASWPW
|
||||||
ANOP
|
|
||||||
ARFE
|
ARFE
|
||||||
ASWI
|
ASWI
|
||||||
AMULA
|
AMULA
|
||||||
ADATA
|
|
||||||
AGLOBL
|
|
||||||
AGOK
|
|
||||||
AHISTORY
|
|
||||||
ANAME
|
|
||||||
ARET
|
|
||||||
ATEXT
|
|
||||||
AWORD
|
AWORD
|
||||||
ADYNT_
|
|
||||||
AINIT_
|
|
||||||
ABCASE
|
ABCASE
|
||||||
ACASE
|
ACASE
|
||||||
AEND
|
|
||||||
AMULL
|
AMULL
|
||||||
AMULAL
|
AMULAL
|
||||||
AMULLU
|
AMULLU
|
||||||
@ -214,31 +227,22 @@ const (
|
|||||||
ABX
|
ABX
|
||||||
ABXRET
|
ABXRET
|
||||||
ADWORD
|
ADWORD
|
||||||
ASIGNAME
|
|
||||||
ALDREX
|
ALDREX
|
||||||
ASTREX
|
ASTREX
|
||||||
ALDREXD
|
ALDREXD
|
||||||
ASTREXD
|
ASTREXD
|
||||||
APLD
|
APLD
|
||||||
AUNDEF
|
|
||||||
ACLZ
|
ACLZ
|
||||||
AMULWT
|
AMULWT
|
||||||
AMULWB
|
AMULWB
|
||||||
AMULAWT
|
AMULAWT
|
||||||
AMULAWB
|
AMULAWB
|
||||||
AUSEFIELD
|
|
||||||
ATYPE
|
|
||||||
AFUNCDATA
|
|
||||||
APCDATA
|
|
||||||
ACHECKNIL
|
|
||||||
AVARDEF
|
|
||||||
AVARKILL
|
|
||||||
ADUFFCOPY
|
|
||||||
ADUFFZERO
|
|
||||||
ADATABUNDLE
|
ADATABUNDLE
|
||||||
ADATABUNDLEEND
|
ADATABUNDLEEND
|
||||||
AMRC
|
AMRC
|
||||||
ALAST
|
ALAST
|
||||||
|
AB = obj.AJMP
|
||||||
|
ABL = obj.ACALL
|
||||||
)
|
)
|
||||||
|
|
||||||
/* scond byte */
|
/* scond byte */
|
||||||
@ -249,56 +253,29 @@ const (
|
|||||||
C_WBIT = 1 << 6
|
C_WBIT = 1 << 6
|
||||||
C_FBIT = 1 << 7
|
C_FBIT = 1 << 7
|
||||||
C_UBIT = 1 << 7
|
C_UBIT = 1 << 7
|
||||||
C_SCOND_EQ = 0
|
C_SCOND_XOR = 14
|
||||||
C_SCOND_NE = 1
|
C_SCOND_EQ = 0 ^ C_SCOND_XOR
|
||||||
C_SCOND_HS = 2
|
C_SCOND_NE = 1 ^ C_SCOND_XOR
|
||||||
C_SCOND_LO = 3
|
C_SCOND_HS = 2 ^ C_SCOND_XOR
|
||||||
C_SCOND_MI = 4
|
C_SCOND_LO = 3 ^ C_SCOND_XOR
|
||||||
C_SCOND_PL = 5
|
C_SCOND_MI = 4 ^ C_SCOND_XOR
|
||||||
C_SCOND_VS = 6
|
C_SCOND_PL = 5 ^ C_SCOND_XOR
|
||||||
C_SCOND_VC = 7
|
C_SCOND_VS = 6 ^ C_SCOND_XOR
|
||||||
C_SCOND_HI = 8
|
C_SCOND_VC = 7 ^ C_SCOND_XOR
|
||||||
C_SCOND_LS = 9
|
C_SCOND_HI = 8 ^ C_SCOND_XOR
|
||||||
C_SCOND_GE = 10
|
C_SCOND_LS = 9 ^ C_SCOND_XOR
|
||||||
C_SCOND_LT = 11
|
C_SCOND_GE = 10 ^ C_SCOND_XOR
|
||||||
C_SCOND_GT = 12
|
C_SCOND_LT = 11 ^ C_SCOND_XOR
|
||||||
C_SCOND_LE = 13
|
C_SCOND_GT = 12 ^ C_SCOND_XOR
|
||||||
C_SCOND_NONE = 14
|
C_SCOND_LE = 13 ^ C_SCOND_XOR
|
||||||
C_SCOND_NV = 15
|
C_SCOND_NONE = 14 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_NV = 15 ^ C_SCOND_XOR
|
||||||
SHIFT_LL = 0 << 5
|
SHIFT_LL = 0 << 5
|
||||||
SHIFT_LR = 1 << 5
|
SHIFT_LR = 1 << 5
|
||||||
SHIFT_AR = 2 << 5
|
SHIFT_AR = 2 << 5
|
||||||
SHIFT_RR = 3 << 5
|
SHIFT_RR = 3 << 5
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
D_GOK = 0
|
|
||||||
D_NONE = 1
|
|
||||||
D_BRANCH = D_NONE + 1
|
|
||||||
D_OREG = D_NONE + 2
|
|
||||||
D_CONST = D_NONE + 7
|
|
||||||
D_FCONST = D_NONE + 8
|
|
||||||
D_SCONST = D_NONE + 9
|
|
||||||
D_PSR = D_NONE + 10
|
|
||||||
D_REG = D_NONE + 12
|
|
||||||
D_FREG = D_NONE + 13
|
|
||||||
D_FILE = D_NONE + 16
|
|
||||||
D_OCONST = D_NONE + 17
|
|
||||||
D_FILE1 = D_NONE + 18
|
|
||||||
D_SHIFT = D_NONE + 19
|
|
||||||
D_FPCR = D_NONE + 20
|
|
||||||
D_REGREG = D_NONE + 21
|
|
||||||
D_ADDR = D_NONE + 22
|
|
||||||
D_SBIG = D_NONE + 23
|
|
||||||
D_CONST2 = D_NONE + 24
|
|
||||||
D_REGREG2 = D_NONE + 25
|
|
||||||
D_EXTERN = D_NONE + 3
|
|
||||||
D_STATIC = D_NONE + 4
|
|
||||||
D_AUTO = D_NONE + 5
|
|
||||||
D_PARAM = D_NONE + 6
|
|
||||||
D_LAST = D_NONE + 26
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is the ranlib header
|
* this is the ranlib header
|
||||||
*/
|
*/
|
||||||
|
@ -1,8 +1,26 @@
|
|||||||
package arm
|
package arm
|
||||||
|
|
||||||
var Anames = []string{
|
var Anames = []string{
|
||||||
"XXX",
|
"XXX ",
|
||||||
"AND",
|
"CALL",
|
||||||
|
"CHECKNIL",
|
||||||
|
"DATA",
|
||||||
|
"DUFFCOPY",
|
||||||
|
"DUFFZERO",
|
||||||
|
"END",
|
||||||
|
"FUNCDATA",
|
||||||
|
"GLOBL",
|
||||||
|
"JMP",
|
||||||
|
"NOP",
|
||||||
|
"PCDATA",
|
||||||
|
"RET",
|
||||||
|
"TEXT",
|
||||||
|
"TYPE",
|
||||||
|
"UNDEF",
|
||||||
|
"USEFIELD",
|
||||||
|
"VARDEF",
|
||||||
|
"VARKILL",
|
||||||
|
"AND ",
|
||||||
"EOR",
|
"EOR",
|
||||||
"SUB",
|
"SUB",
|
||||||
"RSB",
|
"RSB",
|
||||||
@ -17,8 +35,6 @@ var Anames = []string{
|
|||||||
"ORR",
|
"ORR",
|
||||||
"BIC",
|
"BIC",
|
||||||
"MVN",
|
"MVN",
|
||||||
"B",
|
|
||||||
"BL",
|
|
||||||
"BEQ",
|
"BEQ",
|
||||||
"BNE",
|
"BNE",
|
||||||
"BCS",
|
"BCS",
|
||||||
@ -76,23 +92,12 @@ var Anames = []string{
|
|||||||
"MOVM",
|
"MOVM",
|
||||||
"SWPBU",
|
"SWPBU",
|
||||||
"SWPW",
|
"SWPW",
|
||||||
"NOP",
|
|
||||||
"RFE",
|
"RFE",
|
||||||
"SWI",
|
"SWI",
|
||||||
"MULA",
|
"MULA",
|
||||||
"DATA",
|
|
||||||
"GLOBL",
|
|
||||||
"GOK",
|
|
||||||
"HISTORY",
|
|
||||||
"NAME",
|
|
||||||
"RET",
|
|
||||||
"TEXT",
|
|
||||||
"WORD",
|
"WORD",
|
||||||
"DYNT_",
|
|
||||||
"INIT_",
|
|
||||||
"BCASE",
|
"BCASE",
|
||||||
"CASE",
|
"CASE",
|
||||||
"END",
|
|
||||||
"MULL",
|
"MULL",
|
||||||
"MULAL",
|
"MULAL",
|
||||||
"MULLU",
|
"MULLU",
|
||||||
@ -100,27 +105,16 @@ var Anames = []string{
|
|||||||
"BX",
|
"BX",
|
||||||
"BXRET",
|
"BXRET",
|
||||||
"DWORD",
|
"DWORD",
|
||||||
"SIGNAME",
|
|
||||||
"LDREX",
|
"LDREX",
|
||||||
"STREX",
|
"STREX",
|
||||||
"LDREXD",
|
"LDREXD",
|
||||||
"STREXD",
|
"STREXD",
|
||||||
"PLD",
|
"PLD",
|
||||||
"UNDEF",
|
|
||||||
"CLZ",
|
"CLZ",
|
||||||
"MULWT",
|
"MULWT",
|
||||||
"MULWB",
|
"MULWB",
|
||||||
"MULAWT",
|
"MULAWT",
|
||||||
"MULAWB",
|
"MULAWB",
|
||||||
"USEFIELD",
|
|
||||||
"TYPE",
|
|
||||||
"FUNCDATA",
|
|
||||||
"PCDATA",
|
|
||||||
"CHECKNIL",
|
|
||||||
"VARDEF",
|
|
||||||
"VARKILL",
|
|
||||||
"DUFFCOPY",
|
|
||||||
"DUFFZERO",
|
|
||||||
"DATABUNDLE",
|
"DATABUNDLE",
|
||||||
"DATABUNDLEEND",
|
"DATABUNDLEEND",
|
||||||
"MRC",
|
"MRC",
|
||||||
@ -164,6 +158,7 @@ var cnames5 = []string{
|
|||||||
"SP",
|
"SP",
|
||||||
"HREG",
|
"HREG",
|
||||||
"ADDR",
|
"ADDR",
|
||||||
|
"TEXTSIZE",
|
||||||
"GOK",
|
"GOK",
|
||||||
"NCLASS",
|
"NCLASS",
|
||||||
"SCOND = (1<<4)-1",
|
"SCOND = (1<<4)-1",
|
||||||
@ -172,25 +167,21 @@ var cnames5 = []string{
|
|||||||
"WBIT = 1<<6",
|
"WBIT = 1<<6",
|
||||||
"FBIT = 1<<7",
|
"FBIT = 1<<7",
|
||||||
"UBIT = 1<<7",
|
"UBIT = 1<<7",
|
||||||
"SCOND_EQ = 0",
|
"SCOND_XOR = 14",
|
||||||
"SCOND_NE = 1",
|
"SCOND_EQ = 0 ^ C_SCOND_XOR",
|
||||||
"SCOND_HS = 2",
|
"SCOND_NE = 1 ^ C_SCOND_XOR",
|
||||||
"SCOND_LO = 3",
|
"SCOND_HS = 2 ^ C_SCOND_XOR",
|
||||||
"SCOND_MI = 4",
|
"SCOND_LO = 3 ^ C_SCOND_XOR",
|
||||||
"SCOND_PL = 5",
|
"SCOND_MI = 4 ^ C_SCOND_XOR",
|
||||||
"SCOND_VS = 6",
|
"SCOND_PL = 5 ^ C_SCOND_XOR",
|
||||||
"SCOND_VC = 7",
|
"SCOND_VS = 6 ^ C_SCOND_XOR",
|
||||||
"SCOND_HI = 8",
|
"SCOND_VC = 7 ^ C_SCOND_XOR",
|
||||||
"SCOND_LS = 9",
|
"SCOND_HI = 8 ^ C_SCOND_XOR",
|
||||||
"SCOND_GE = 10",
|
"SCOND_LS = 9 ^ C_SCOND_XOR",
|
||||||
"SCOND_LT = 11",
|
"SCOND_GE = 10 ^ C_SCOND_XOR",
|
||||||
"SCOND_GT = 12",
|
"SCOND_LT = 11 ^ C_SCOND_XOR",
|
||||||
"SCOND_LE = 13",
|
"SCOND_GT = 12 ^ C_SCOND_XOR",
|
||||||
"SCOND_NONE = 14",
|
"SCOND_LE = 13 ^ C_SCOND_XOR",
|
||||||
"SCOND_NV = 15",
|
"SCOND_NONE = 14 ^ C_SCOND_XOR",
|
||||||
}
|
"SCOND_NV = 15 ^ C_SCOND_XOR",
|
||||||
|
|
||||||
var dnames5 = []string{
|
|
||||||
D_GOK: "GOK",
|
|
||||||
D_NONE: "NONE",
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -70,7 +70,7 @@ func Pconv(p *obj.Prog) string {
|
|||||||
|
|
||||||
a = int(p.As)
|
a = int(p.As)
|
||||||
s = int(p.Scond)
|
s = int(p.Scond)
|
||||||
sc = extra[s&C_SCOND]
|
sc = extra[(s&C_SCOND)^C_SCOND_XOR]
|
||||||
if s&C_SBIT != 0 {
|
if s&C_SBIT != 0 {
|
||||||
sc += ".S"
|
sc += ".S"
|
||||||
}
|
}
|
||||||
@ -84,25 +84,21 @@ func Pconv(p *obj.Prog) string {
|
|||||||
sc += ".U"
|
sc += ".U"
|
||||||
}
|
}
|
||||||
if a == AMOVM {
|
if a == AMOVM {
|
||||||
if p.From.Type == D_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), Dconv(p, 0, &p.To))
|
||||||
} else if p.To.Type == D_CONST {
|
} else if p.To.Type == obj.TYPE_CONST {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), RAconv(&p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), RAconv(&p.To))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
||||||
}
|
}
|
||||||
} else if a == ADATA {
|
} else if a == obj.ADATA {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
|
||||||
} else if p.As == ATEXT {
|
} else if p.As == obj.ATEXT {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
|
||||||
} else if p.Reg == NREG {
|
} else if p.Reg == 0 {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
||||||
} else if p.From.Type != D_FREG {
|
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,R%d,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
|
|
||||||
} else {
|
} else {
|
||||||
|
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Rconv(int(p.Reg)), Dconv(p, 0, &p.To))
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,F%d,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fp += str
|
fp += str
|
||||||
@ -114,7 +110,7 @@ func Aconv(a int) string {
|
|||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
s = "???"
|
s = "???"
|
||||||
if a >= AXXX && a < ALAST {
|
if a >= obj.AXXX && a < ALAST {
|
||||||
s = Anames[a]
|
s = Anames[a]
|
||||||
}
|
}
|
||||||
fp += s
|
fp += s
|
||||||
@ -132,63 +128,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
|
|||||||
default:
|
default:
|
||||||
str = fmt.Sprintf("GOK-type(%d)", a.Type)
|
str = fmt.Sprintf("GOK-type(%d)", a.Type)
|
||||||
|
|
||||||
case D_NONE:
|
case obj.TYPE_NONE:
|
||||||
str = ""
|
str = ""
|
||||||
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil {
|
if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil {
|
||||||
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg)
|
str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_CONST:
|
case obj.TYPE_CONST,
|
||||||
if a.Reg != NREG {
|
obj.TYPE_ADDR:
|
||||||
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg)
|
if a.Reg != 0 {
|
||||||
|
str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("$%v", Mconv(a))
|
str = fmt.Sprintf("$%v", Mconv(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_CONST2:
|
case obj.TYPE_TEXTSIZE:
|
||||||
str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2)
|
if a.U.Argsize == obj.ArgsSizeUnknown {
|
||||||
|
str = fmt.Sprintf("$%d", a.Offset)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
|
||||||
|
}
|
||||||
|
|
||||||
case D_SHIFT:
|
case obj.TYPE_SHIFT:
|
||||||
v = int(a.Offset)
|
v = int(a.Offset)
|
||||||
op = string("<<>>->@>"[((v>>5)&3)<<1:])
|
op = string("<<>>->@>"[((v>>5)&3)<<1:])
|
||||||
if v&(1<<4) != 0 {
|
if v&(1<<4) != 0 {
|
||||||
str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15)
|
str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31)
|
str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31)
|
||||||
}
|
}
|
||||||
if a.Reg != NREG {
|
if a.Reg != 0 {
|
||||||
str += fmt.Sprintf("(R%d)", a.Reg)
|
str += fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_OREG:
|
case obj.TYPE_MEM:
|
||||||
if a.Reg != NREG {
|
if a.Reg != 0 {
|
||||||
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg)
|
str = fmt.Sprintf("%v(%v)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%v", Mconv(a))
|
str = fmt.Sprintf("%v", Mconv(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_REG:
|
case obj.TYPE_REG:
|
||||||
str = fmt.Sprintf("R%d", a.Reg)
|
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
|
||||||
if a.Name != D_NONE || a.Sym != nil {
|
if a.Name != obj.TYPE_NONE || a.Sym != nil {
|
||||||
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
|
str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_FREG:
|
case obj.TYPE_BRANCH:
|
||||||
str = fmt.Sprintf("F%d", a.Reg)
|
|
||||||
if a.Name != D_NONE || a.Sym != nil {
|
|
||||||
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
case D_PSR:
|
|
||||||
str = fmt.Sprintf("PSR")
|
|
||||||
if a.Name != D_NONE || a.Sym != nil {
|
|
||||||
str = fmt.Sprintf("%v(PSR)(REG)", Mconv(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
case D_BRANCH:
|
|
||||||
if a.Sym != nil {
|
if a.Sym != nil {
|
||||||
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
|
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
|
||||||
} else if p != nil && p.Pcond != nil {
|
} else if p != nil && p.Pcond != nil {
|
||||||
@ -196,14 +182,13 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
|
|||||||
} else if a.U.Branch != nil {
|
} else if a.U.Branch != nil {
|
||||||
str = fmt.Sprintf("%d", a.U.Branch.Pc)
|
str = fmt.Sprintf("%d", a.U.Branch.Pc)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%d(PC)", a.Offset) /*-pc*/
|
str = fmt.Sprintf("%d(PC)", a.Offset) /*-pc*/
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_FCONST:
|
case obj.TYPE_FCONST:
|
||||||
str = fmt.Sprintf("$%.17g", a.U.Dval)
|
str = fmt.Sprintf("$%.17g", a.U.Dval)
|
||||||
|
|
||||||
case D_SCONST:
|
case obj.TYPE_SCONST:
|
||||||
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -221,9 +206,8 @@ func RAconv(a *obj.Addr) string {
|
|||||||
|
|
||||||
str = fmt.Sprintf("GOK-reglist")
|
str = fmt.Sprintf("GOK-reglist")
|
||||||
switch a.Type {
|
switch a.Type {
|
||||||
case D_CONST,
|
case obj.TYPE_CONST:
|
||||||
D_CONST2:
|
if a.Reg != 0 {
|
||||||
if a.Reg != NREG {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if a.Sym != nil {
|
if a.Sym != nil {
|
||||||
@ -233,10 +217,9 @@ func RAconv(a *obj.Addr) string {
|
|||||||
str = ""
|
str = ""
|
||||||
for i = 0; i < NREG; i++ {
|
for i = 0; i < NREG; i++ {
|
||||||
if v&(1<<uint(i)) != 0 {
|
if v&(1<<uint(i)) != 0 {
|
||||||
if str[0] == 0 {
|
if str == "" {
|
||||||
str += "[R"
|
str += "[R"
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str += ",R"
|
str += ",R"
|
||||||
}
|
}
|
||||||
str += fmt.Sprintf("%d", i)
|
str += fmt.Sprintf("%d", i)
|
||||||
@ -253,10 +236,38 @@ func RAconv(a *obj.Addr) string {
|
|||||||
func Rconv(r int) string {
|
func Rconv(r int) string {
|
||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
var str string
|
if r == 0 {
|
||||||
|
fp += "NONE"
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if REG_R0 <= r && r <= REG_R15 {
|
||||||
|
fp += fmt.Sprintf("R%d", r-REG_R0)
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if REG_F0 <= r && r <= REG_F15 {
|
||||||
|
fp += fmt.Sprintf("F%d", r-REG_F0)
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
|
||||||
str = fmt.Sprintf("R%d", r)
|
switch r {
|
||||||
fp += str
|
case REG_FPSR:
|
||||||
|
fp += "FPSR"
|
||||||
|
return fp
|
||||||
|
|
||||||
|
case REG_FPCR:
|
||||||
|
fp += "FPCR"
|
||||||
|
return fp
|
||||||
|
|
||||||
|
case REG_CPSR:
|
||||||
|
fp += "CPSR"
|
||||||
|
return fp
|
||||||
|
|
||||||
|
case REG_SPSR:
|
||||||
|
fp += "SPSR"
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
|
||||||
|
fp += fmt.Sprintf("badreg(%d)", r)
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,19 +299,19 @@ func Mconv(a *obj.Addr) string {
|
|||||||
default:
|
default:
|
||||||
str = fmt.Sprintf("GOK-name(%d)", a.Name)
|
str = fmt.Sprintf("GOK-name(%d)", a.Name)
|
||||||
|
|
||||||
case D_NONE:
|
case obj.NAME_NONE:
|
||||||
str = fmt.Sprintf("%d", a.Offset)
|
str = fmt.Sprintf("%d", a.Offset)
|
||||||
|
|
||||||
case D_EXTERN:
|
case obj.NAME_EXTERN:
|
||||||
str = fmt.Sprintf("%s+%d(SB)", s.Name, int(a.Offset))
|
str = fmt.Sprintf("%s+%d(SB)", s.Name, int(a.Offset))
|
||||||
|
|
||||||
case D_STATIC:
|
case obj.NAME_STATIC:
|
||||||
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, int(a.Offset))
|
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, int(a.Offset))
|
||||||
|
|
||||||
case D_AUTO:
|
case obj.NAME_AUTO:
|
||||||
str = fmt.Sprintf("%s-%d(SP)", s.Name, int(-a.Offset))
|
str = fmt.Sprintf("%s-%d(SP)", s.Name, int(-a.Offset))
|
||||||
|
|
||||||
case D_PARAM:
|
case obj.NAME_PARAM:
|
||||||
str = fmt.Sprintf("%s+%d(FP)", s.Name, int(a.Offset))
|
str = fmt.Sprintf("%s+%d(FP)", s.Name, int(a.Offset))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -38,46 +38,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
var zprg5 = obj.Prog{
|
|
||||||
As: AGOK,
|
|
||||||
Scond: C_SCOND_NONE,
|
|
||||||
Reg: NREG,
|
|
||||||
From: obj.Addr{
|
|
||||||
Name: D_NONE,
|
|
||||||
Type: D_NONE,
|
|
||||||
Reg: NREG,
|
|
||||||
},
|
|
||||||
To: obj.Addr{
|
|
||||||
Name: D_NONE,
|
|
||||||
Type: D_NONE,
|
|
||||||
Reg: NREG,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func symtype(a *obj.Addr) int {
|
|
||||||
return int(a.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isdata(p *obj.Prog) bool {
|
|
||||||
return p.As == ADATA || p.As == AGLOBL
|
|
||||||
}
|
|
||||||
|
|
||||||
func iscall(p *obj.Prog) bool {
|
|
||||||
return p.As == ABL
|
|
||||||
}
|
|
||||||
|
|
||||||
func datasize(p *obj.Prog) int {
|
|
||||||
return int(p.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func textflag(p *obj.Prog) int {
|
|
||||||
return int(p.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func settextflag(p *obj.Prog, f int) {
|
|
||||||
p.Reg = uint8(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
var literal string
|
var literal string
|
||||||
var s *obj.LSym
|
var s *obj.LSym
|
||||||
@ -86,53 +46,48 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
p.From.Class = 0
|
p.From.Class = 0
|
||||||
p.To.Class = 0
|
p.To.Class = 0
|
||||||
|
|
||||||
// Rewrite B/BL to symbol as D_BRANCH.
|
// Rewrite B/BL to symbol as TYPE_BRANCH.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
|
||||||
case AB,
|
case AB,
|
||||||
ABL,
|
ABL,
|
||||||
ADUFFZERO,
|
obj.ADUFFZERO,
|
||||||
ADUFFCOPY:
|
obj.ADUFFCOPY:
|
||||||
if p.To.Type == D_OREG && (p.To.Name == D_EXTERN || p.To.Name == D_STATIC) && p.To.Sym != nil {
|
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 = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace TLS register fetches on older ARM procesors.
|
// Replace TLS register fetches on older ARM procesors.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
|
||||||
// Treat MRC 15, 0, <reg>, C13, C0, 3 specially.
|
// Treat MRC 15, 0, <reg>, C13, C0, 3 specially.
|
||||||
case AMRC:
|
case AMRC:
|
||||||
if p.To.Offset&0xffff0fff == 0xee1d0f70 {
|
if p.To.Offset&0xffff0fff == 0xee1d0f70 {
|
||||||
|
|
||||||
// Because the instruction might be rewriten to a BL which returns in R0
|
// Because the instruction might be rewriten to a BL which returns in R0
|
||||||
// the register must be zero.
|
// the register must be zero.
|
||||||
if p.To.Offset&0xf000 != 0 {
|
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())
|
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 {
|
if ctxt.Goarm < 7 {
|
||||||
// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
|
// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
|
||||||
if tlsfallback == nil {
|
if tlsfallback == nil {
|
||||||
|
|
||||||
tlsfallback = obj.Linklookup(ctxt, "runtime.read_tls_fallback", 0)
|
tlsfallback = obj.Linklookup(ctxt, "runtime.read_tls_fallback", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOVW LR, R11
|
// MOVW LR, R11
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
|
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REGLINK
|
p.From.Reg = REGLINK
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGTMP
|
p.To.Reg = REGTMP
|
||||||
|
|
||||||
// BL runtime.read_tls_fallback(SB)
|
// BL runtime.read_tls_fallback(SB)
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ABL
|
p.As = ABL
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.To.Sym = tlsfallback
|
p.To.Sym = tlsfallback
|
||||||
p.To.Offset = 0
|
p.To.Offset = 0
|
||||||
|
|
||||||
@ -140,9 +95,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REGTMP
|
p.From.Reg = REGTMP
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGLINK
|
p.To.Reg = REGLINK
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -156,9 +111,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
|
|
||||||
// Rewrite float constants to values stored in memory.
|
// Rewrite float constants to values stored in memory.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
|
||||||
case AMOVF:
|
case AMOVF:
|
||||||
if p.From.Type == D_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
|
if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
|
||||||
var i32 uint32
|
var i32 uint32
|
||||||
var f32 float32
|
var f32 float32
|
||||||
f32 = float32(p.From.U.Dval)
|
f32 = float32(p.From.U.Dval)
|
||||||
@ -171,14 +125,14 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
s.Reachable = 0
|
s.Reachable = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
p.From.Name = D_EXTERN
|
p.From.Name = obj.NAME_EXTERN
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
case AMOVD:
|
case AMOVD:
|
||||||
if p.From.Type == D_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
|
if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
|
||||||
var i64 uint64
|
var i64 uint64
|
||||||
i64 = math.Float64bits(p.From.U.Dval)
|
i64 = math.Float64bits(p.From.U.Dval)
|
||||||
literal = fmt.Sprintf("$f64.%016x", i64)
|
literal = fmt.Sprintf("$f64.%016x", i64)
|
||||||
@ -189,9 +143,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
s.Reachable = 0
|
s.Reachable = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
p.From.Name = D_EXTERN
|
p.From.Name = obj.NAME_EXTERN
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,24 +159,18 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
// offset. Rewrite $runtime.tlsg(SB) to runtime.tlsg(SB) to
|
// offset. Rewrite $runtime.tlsg(SB) to runtime.tlsg(SB) to
|
||||||
// compensate.
|
// compensate.
|
||||||
if ctxt.Tlsg == nil {
|
if ctxt.Tlsg == nil {
|
||||||
|
|
||||||
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
|
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.From.Type == D_CONST && p.From.Name == D_EXTERN && p.From.Sym == ctxt.Tlsg {
|
if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && p.From.Sym == ctxt.Tlsg {
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
}
|
}
|
||||||
if p.To.Type == D_CONST && p.To.Name == D_EXTERN && p.To.Sym == ctxt.Tlsg {
|
if p.To.Type == obj.TYPE_ADDR && p.To.Name == obj.NAME_EXTERN && p.To.Sym == ctxt.Tlsg {
|
||||||
p.To.Type = D_OREG
|
p.To.Type = obj.TYPE_MEM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func prg() *obj.Prog {
|
|
||||||
p := zprg
|
|
||||||
return &p
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prog.mark
|
// Prog.mark
|
||||||
const (
|
const (
|
||||||
FOLL = 1 << 0
|
FOLL = 1 << 0
|
||||||
@ -249,7 +197,7 @@ func nocache5(p *obj.Prog) {
|
|||||||
p.To.Class = 0
|
p.To.Class = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
var p *obj.Prog
|
||||||
var pl *obj.Prog
|
var pl *obj.Prog
|
||||||
var p1 *obj.Prog
|
var p1 *obj.Prog
|
||||||
@ -284,38 +232,38 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
autoffset = 0
|
autoffset = 0
|
||||||
}
|
}
|
||||||
cursym.Locals = autoffset
|
cursym.Locals = autoffset
|
||||||
cursym.Args = p.To.Offset2
|
cursym.Args = p.To.U.Argsize
|
||||||
|
|
||||||
if ctxt.Debugzerostack != 0 {
|
if ctxt.Debugzerostack != 0 {
|
||||||
if autoffset != 0 && !(p.Reg&obj.NOSPLIT != 0) {
|
if autoffset != 0 && !(p.From3.Offset&obj.NOSPLIT != 0) {
|
||||||
// MOVW $4(R13), R1
|
// MOVW $4(R13), R1
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Reg = 13
|
p.From.Reg = REG_R13
|
||||||
p.From.Offset = 4
|
p.From.Offset = 4
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 1
|
p.To.Reg = REG_R1
|
||||||
|
|
||||||
// MOVW $n(R13), R2
|
// MOVW $n(R13), R2
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Reg = 13
|
p.From.Reg = REG_R13
|
||||||
p.From.Offset = 4 + int64(autoffset)
|
p.From.Offset = 4 + int64(autoffset)
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 2
|
p.To.Reg = REG_R2
|
||||||
|
|
||||||
// MOVW $0, R3
|
// MOVW $0, R3
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 3
|
p.To.Reg = REG_R3
|
||||||
|
|
||||||
// L:
|
// L:
|
||||||
// MOVW.nil R3, 0(R1) +4
|
// MOVW.nil R3, 0(R1) +4
|
||||||
@ -325,22 +273,22 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
p = pl
|
p = pl
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 3
|
p.From.Reg = REG_R3
|
||||||
p.To.Type = D_OREG
|
p.To.Type = obj.TYPE_MEM
|
||||||
p.To.Reg = 1
|
p.To.Reg = REG_R1
|
||||||
p.To.Offset = 4
|
p.To.Offset = 4
|
||||||
p.Scond |= C_PBIT
|
p.Scond |= C_PBIT
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 1
|
p.From.Reg = REG_R1
|
||||||
p.Reg = 2
|
p.Reg = REG_R2
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ABNE
|
p.As = ABNE
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.Pcond = pl
|
p.Pcond = pl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,17 +300,16 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
* expand BECOME pseudo
|
* expand BECOME pseudo
|
||||||
*/
|
*/
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p = cursym.Text; p != nil; p = p.Link {
|
||||||
|
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ACASE:
|
case ACASE:
|
||||||
if ctxt.Flag_shared != 0 {
|
if ctxt.Flag_shared != 0 {
|
||||||
linkcase(p)
|
linkcase(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ATEXT:
|
case obj.ATEXT:
|
||||||
p.Mark |= LEAF
|
p.Mark |= LEAF
|
||||||
|
|
||||||
case ARET:
|
case obj.ARET:
|
||||||
break
|
break
|
||||||
|
|
||||||
case ADIV,
|
case ADIV,
|
||||||
@ -376,7 +323,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
cursym.Text.Mark &^= LEAF
|
cursym.Text.Mark &^= LEAF
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case ANOP:
|
case obj.ANOP:
|
||||||
q1 = p.Link
|
q1 = p.Link
|
||||||
q.Link = q1 /* q is non-nop */
|
q.Link = q1 /* q is non-nop */
|
||||||
if q1 != nil {
|
if q1 != nil {
|
||||||
@ -386,8 +333,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
case ABL,
|
case ABL,
|
||||||
ABX,
|
ABX,
|
||||||
ADUFFZERO,
|
obj.ADUFFZERO,
|
||||||
ADUFFCOPY:
|
obj.ADUFFCOPY:
|
||||||
cursym.Text.Mark &^= LEAF
|
cursym.Text.Mark &^= LEAF
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
@ -411,7 +358,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
ABLE:
|
ABLE:
|
||||||
q1 = p.Pcond
|
q1 = p.Pcond
|
||||||
if q1 != nil {
|
if q1 != nil {
|
||||||
for q1.As == ANOP {
|
for q1.As == obj.ANOP {
|
||||||
q1 = q1.Link
|
q1 = q1.Link
|
||||||
p.Pcond = q1
|
p.Pcond = q1
|
||||||
}
|
}
|
||||||
@ -426,7 +373,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p = cursym.Text; p != nil; p = p.Link {
|
||||||
o = int(p.As)
|
o = int(p.As)
|
||||||
switch o {
|
switch o {
|
||||||
case ATEXT:
|
case obj.ATEXT:
|
||||||
autosize = int32(p.To.Offset + 4)
|
autosize = int32(p.To.Offset + 4)
|
||||||
if autosize <= 4 {
|
if autosize <= 4 {
|
||||||
if cursym.Text.Mark&LEAF != 0 {
|
if cursym.Text.Mark&LEAF != 0 {
|
||||||
@ -451,8 +398,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(p.Reg&obj.NOSPLIT != 0) {
|
if !(p.From3.Offset&obj.NOSPLIT != 0) {
|
||||||
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.Reg&obj.NEEDCTXT != 0))) // emit split check
|
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0))) // emit split check
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOVW.W R14,$-autosize(SP)
|
// MOVW.W R14,$-autosize(SP)
|
||||||
@ -460,14 +407,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.Scond |= C_WBIT
|
p.Scond |= C_WBIT
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REGLINK
|
p.From.Reg = REGLINK
|
||||||
p.To.Type = D_OREG
|
p.To.Type = obj.TYPE_MEM
|
||||||
p.To.Offset = int64(-autosize)
|
p.To.Offset = int64(-autosize)
|
||||||
p.To.Reg = REGSP
|
p.To.Reg = REGSP
|
||||||
p.Spadj = autosize
|
p.Spadj = autosize
|
||||||
|
|
||||||
if cursym.Text.Reg&obj.WRAPPER != 0 {
|
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||||
//
|
//
|
||||||
// MOVW g_panic(g), R1
|
// MOVW g_panic(g), R1
|
||||||
@ -488,84 +435,83 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Reg = REGG
|
p.From.Reg = REGG
|
||||||
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
|
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 1
|
p.To.Reg = REG_R1
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
p.Reg = 1
|
p.Reg = REG_R1
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ABEQ
|
p.As = ABEQ
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p1 = p
|
p1 = p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Reg = 1
|
p.From.Reg = REG_R1
|
||||||
p.From.Offset = 0 // Panic.argp
|
p.From.Offset = 0 // Panic.argp
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 2
|
p.To.Reg = REG_R2
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(autosize) + 4
|
p.From.Offset = int64(autosize) + 4
|
||||||
p.Reg = 13
|
p.Reg = REG_R13
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 3
|
p.To.Reg = REG_R3
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 2
|
p.From.Reg = REG_R2
|
||||||
p.Reg = 3
|
p.Reg = REG_R3
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ABNE
|
p.As = ABNE
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p2 = p
|
p2 = p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = 4
|
p.From.Offset = 4
|
||||||
p.Reg = 13
|
p.Reg = REG_R13
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 4
|
p.To.Reg = REG_R4
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 4
|
p.From.Reg = REG_R4
|
||||||
p.To.Type = D_OREG
|
p.To.Type = obj.TYPE_MEM
|
||||||
p.To.Reg = 1
|
p.To.Reg = REG_R1
|
||||||
p.To.Offset = 0 // Panic.argp
|
p.To.Offset = 0 // Panic.argp
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ANOP
|
p.As = obj.ANOP
|
||||||
p1.Pcond = p
|
p1.Pcond = p
|
||||||
p2.Pcond = p
|
p2.Pcond = p
|
||||||
}
|
}
|
||||||
|
|
||||||
case ARET:
|
case obj.ARET:
|
||||||
nocache5(p)
|
nocache5(p)
|
||||||
if cursym.Text.Mark&LEAF != 0 {
|
if cursym.Text.Mark&LEAF != 0 {
|
||||||
if !(autosize != 0) {
|
if !(autosize != 0) {
|
||||||
p.As = AB
|
p.As = AB
|
||||||
p.From = zprg5.From
|
p.From = obj.Zprog.From
|
||||||
if p.To.Sym != nil { // retjmp
|
if p.To.Sym != nil { // retjmp
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
} else {
|
} else {
|
||||||
|
p.To.Type = obj.TYPE_MEM
|
||||||
p.To.Type = D_OREG
|
|
||||||
p.To.Offset = 0
|
p.To.Offset = 0
|
||||||
p.To.Reg = REGLINK
|
p.To.Reg = REGLINK
|
||||||
}
|
}
|
||||||
@ -576,10 +522,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.Scond |= C_PBIT
|
p.Scond |= C_PBIT
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Offset = int64(autosize)
|
p.From.Offset = int64(autosize)
|
||||||
p.From.Reg = REGSP
|
p.From.Reg = REGSP
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGPC
|
p.To.Reg = REGPC
|
||||||
|
|
||||||
// If there are instructions following
|
// If there are instructions following
|
||||||
@ -589,19 +535,19 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
p.To.Reg = REGLINK
|
p.To.Reg = REGLINK
|
||||||
q2 = obj.Appendp(ctxt, p)
|
q2 = obj.Appendp(ctxt, p)
|
||||||
q2.As = AB
|
q2.As = AB
|
||||||
q2.To.Type = D_BRANCH
|
q2.To.Type = obj.TYPE_BRANCH
|
||||||
q2.To.Sym = p.To.Sym
|
q2.To.Sym = p.To.Sym
|
||||||
p.To.Sym = nil
|
p.To.Sym = nil
|
||||||
p = q2
|
p = q2
|
||||||
}
|
}
|
||||||
|
|
||||||
case AADD:
|
case AADD:
|
||||||
if p.From.Type == D_CONST && p.From.Reg == NREG && p.To.Type == D_REG && p.To.Reg == REGSP {
|
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)
|
p.Spadj = int32(-p.From.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ASUB:
|
case ASUB:
|
||||||
if p.From.Type == D_CONST && p.From.Reg == NREG && p.To.Type == D_REG && p.To.Reg == REGSP {
|
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)
|
p.Spadj = int32(p.From.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,10 +558,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
if ctxt.Debugdivmod != 0 {
|
if ctxt.Debugdivmod != 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if p.From.Type != D_REG {
|
if p.From.Type != obj.TYPE_REG {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if p.To.Type != D_REG {
|
if p.To.Type != obj.TYPE_REG {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
q1 = p
|
q1 = p
|
||||||
@ -625,9 +571,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.Lineno = q1.Lineno
|
p.Lineno = q1.Lineno
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = q1.From.Reg
|
p.From.Reg = q1.From.Reg
|
||||||
p.To.Type = D_OREG
|
p.To.Type = obj.TYPE_MEM
|
||||||
p.To.Reg = REGSP
|
p.To.Reg = REGSP
|
||||||
p.To.Offset = 4
|
p.To.Offset = 4
|
||||||
|
|
||||||
@ -636,12 +582,12 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.Lineno = q1.Lineno
|
p.Lineno = q1.Lineno
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = int8(q1.Reg)
|
p.From.Reg = q1.Reg
|
||||||
if q1.Reg == NREG {
|
if q1.Reg == 0 {
|
||||||
p.From.Reg = q1.To.Reg
|
p.From.Reg = q1.To.Reg
|
||||||
}
|
}
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGTMP
|
p.To.Reg = REGTMP
|
||||||
p.To.Offset = 0
|
p.To.Offset = 0
|
||||||
|
|
||||||
@ -650,7 +596,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
p.As = ABL
|
p.As = ABL
|
||||||
p.Lineno = q1.Lineno
|
p.Lineno = q1.Lineno
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
switch o {
|
switch o {
|
||||||
case ADIV:
|
case ADIV:
|
||||||
p.To.Sym = ctxt.Sym_div
|
p.To.Sym = ctxt.Sym_div
|
||||||
@ -671,10 +617,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.Lineno = q1.Lineno
|
p.Lineno = q1.Lineno
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REGTMP
|
p.From.Reg = REGTMP
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = q1.To.Reg
|
p.To.Reg = q1.To.Reg
|
||||||
|
|
||||||
/* ADD $8,SP */
|
/* ADD $8,SP */
|
||||||
@ -682,11 +628,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
p.Lineno = q1.Lineno
|
p.Lineno = q1.Lineno
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Reg = NREG
|
p.From.Reg = 0
|
||||||
p.From.Offset = 8
|
p.From.Offset = 8
|
||||||
p.Reg = NREG
|
p.Reg = 0
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGSP
|
p.To.Reg = REGSP
|
||||||
p.Spadj = -8
|
p.Spadj = -8
|
||||||
|
|
||||||
@ -695,34 +641,34 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
/* TODO: Remove SP adjustments; see issue 6699. */
|
/* TODO: Remove SP adjustments; see issue 6699. */
|
||||||
q1.As = AMOVW
|
q1.As = AMOVW
|
||||||
|
|
||||||
q1.From.Type = D_OREG
|
q1.From.Type = obj.TYPE_MEM
|
||||||
q1.From.Reg = REGSP
|
q1.From.Reg = REGSP
|
||||||
q1.From.Offset = 0
|
q1.From.Offset = 0
|
||||||
q1.Reg = NREG
|
q1.Reg = 0
|
||||||
q1.To.Type = D_REG
|
q1.To.Type = obj.TYPE_REG
|
||||||
q1.To.Reg = REGTMP
|
q1.To.Reg = REGTMP
|
||||||
|
|
||||||
/* SUB $8,SP */
|
/* SUB $8,SP */
|
||||||
q1 = obj.Appendp(ctxt, q1)
|
q1 = obj.Appendp(ctxt, q1)
|
||||||
|
|
||||||
q1.As = AMOVW
|
q1.As = AMOVW
|
||||||
q1.From.Type = D_REG
|
q1.From.Type = obj.TYPE_REG
|
||||||
q1.From.Reg = REGTMP
|
q1.From.Reg = REGTMP
|
||||||
q1.Reg = NREG
|
q1.Reg = 0
|
||||||
q1.To.Type = D_OREG
|
q1.To.Type = obj.TYPE_MEM
|
||||||
q1.To.Reg = REGSP
|
q1.To.Reg = REGSP
|
||||||
q1.To.Offset = -8
|
q1.To.Offset = -8
|
||||||
q1.Scond |= C_WBIT
|
q1.Scond |= C_WBIT
|
||||||
q1.Spadj = 8
|
q1.Spadj = 8
|
||||||
|
|
||||||
case AMOVW:
|
case AMOVW:
|
||||||
if (p.Scond&C_WBIT != 0) && p.To.Type == D_OREG && p.To.Reg == REGSP {
|
if (p.Scond&C_WBIT != 0) && p.To.Type == obj.TYPE_MEM && p.To.Reg == REGSP {
|
||||||
p.Spadj = int32(-p.To.Offset)
|
p.Spadj = int32(-p.To.Offset)
|
||||||
}
|
}
|
||||||
if (p.Scond&C_PBIT != 0) && p.From.Type == D_OREG && p.From.Reg == REGSP && p.To.Reg != REGPC {
|
if (p.Scond&C_PBIT != 0) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REGSP && p.To.Reg != REGPC {
|
||||||
p.Spadj = int32(-p.From.Offset)
|
p.Spadj = int32(-p.From.Offset)
|
||||||
}
|
}
|
||||||
if p.From.Type == D_CONST && p.From.Reg == REGSP && p.To.Type == D_REG && p.To.Reg == REGSP {
|
if p.From.Type == obj.TYPE_ADDR && p.From.Reg == REGSP && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP {
|
||||||
p.Spadj = int32(-p.From.Offset)
|
p.Spadj = int32(-p.From.Offset)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -730,6 +676,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isfloatreg(a *obj.Addr) int {
|
||||||
|
return bool2int(a.Type == obj.TYPE_REG && REG_F0 <= a.Reg && a.Reg <= REG_F15)
|
||||||
|
}
|
||||||
|
|
||||||
func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
|
func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
var p *obj.Prog
|
||||||
var next *obj.Prog
|
var next *obj.Prog
|
||||||
@ -751,7 +701,7 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p = cursym.Text; p != nil; p = p.Link {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case AMOVW:
|
case AMOVW:
|
||||||
if p.To.Type == D_FREG || p.From.Type == D_FREG {
|
if isfloatreg(&p.To) != 0 || isfloatreg(&p.From) != 0 {
|
||||||
goto soft
|
goto soft
|
||||||
}
|
}
|
||||||
goto notsoft
|
goto notsoft
|
||||||
@ -786,15 +736,15 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
soft:
|
soft:
|
||||||
if !(wasfloat != 0) || (p.Mark&LABEL != 0) {
|
if !(wasfloat != 0) || (p.Mark&LABEL != 0) {
|
||||||
next = ctxt.NewProg()
|
next = new(obj.Prog)
|
||||||
*next = *p
|
*next = *p
|
||||||
|
|
||||||
// BL _sfloat(SB)
|
// BL _sfloat(SB)
|
||||||
*p = zprg5
|
*p = obj.Zprog
|
||||||
|
|
||||||
p.Link = next
|
p.Link = next
|
||||||
p.As = ABL
|
p.As = ABL
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.To.Sym = symsfloat
|
p.To.Sym = symsfloat
|
||||||
p.Lineno = next.Lineno
|
p.Lineno = next.Lineno
|
||||||
|
|
||||||
@ -814,14 +764,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Reg = REGG
|
p.From.Reg = REGG
|
||||||
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
||||||
if ctxt.Cursym.Cfunc != 0 {
|
if ctxt.Cursym.Cfunc != 0 {
|
||||||
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
||||||
}
|
}
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 1
|
p.To.Reg = REG_R1
|
||||||
|
|
||||||
if framesize <= obj.StackSmall {
|
if framesize <= obj.StackSmall {
|
||||||
// small stack: SP < stackguard
|
// small stack: SP < stackguard
|
||||||
@ -829,8 +779,8 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 1
|
p.From.Reg = REG_R1
|
||||||
p.Reg = REGSP
|
p.Reg = REGSP
|
||||||
} else if framesize <= obj.StackBig {
|
} else if framesize <= obj.StackBig {
|
||||||
// large stack: SP-framesize < stackguard-StackSmall
|
// large stack: SP-framesize < stackguard-StackSmall
|
||||||
@ -839,19 +789,18 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Reg = REGSP
|
p.From.Reg = REGSP
|
||||||
p.From.Offset = int64(-framesize)
|
p.From.Offset = int64(-framesize)
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 2
|
p.To.Reg = REG_R2
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 1
|
p.From.Reg = REG_R1
|
||||||
p.Reg = 2
|
p.Reg = REG_R2
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Such a large stack we need to protect against wraparound
|
// Such a large stack we need to protect against wraparound
|
||||||
// if SP is close to zero.
|
// if SP is close to zero.
|
||||||
// SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall)
|
// SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall)
|
||||||
@ -865,40 +814,40 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
|
p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
|
||||||
p.Reg = 1
|
p.Reg = REG_R1
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Reg = REGSP
|
p.From.Reg = REGSP
|
||||||
p.From.Offset = obj.StackGuard
|
p.From.Offset = obj.StackGuard
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 2
|
p.To.Reg = REG_R2
|
||||||
p.Scond = C_SCOND_NE
|
p.Scond = C_SCOND_NE
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ASUB
|
p.As = ASUB
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 1
|
p.From.Reg = REG_R1
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 2
|
p.To.Reg = REG_R2
|
||||||
p.Scond = C_SCOND_NE
|
p.Scond = C_SCOND_NE
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
|
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 3
|
p.To.Reg = REG_R3
|
||||||
p.Scond = C_SCOND_NE
|
p.Scond = C_SCOND_NE
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 3
|
p.From.Reg = REG_R3
|
||||||
p.Reg = 2
|
p.Reg = REG_R2
|
||||||
p.Scond = C_SCOND_NE
|
p.Scond = C_SCOND_NE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,21 +856,20 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.Scond = C_SCOND_LS
|
p.Scond = C_SCOND_LS
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REGLINK
|
p.From.Reg = REGLINK
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 3
|
p.To.Reg = REG_R3
|
||||||
|
|
||||||
// BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted
|
// BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ABL
|
p.As = ABL
|
||||||
p.Scond = C_SCOND_LS
|
p.Scond = C_SCOND_LS
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
if ctxt.Cursym.Cfunc != 0 {
|
if ctxt.Cursym.Cfunc != 0 {
|
||||||
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
|
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
p.To.Sym = ctxt.Symmorestack[noctxt]
|
p.To.Sym = ctxt.Symmorestack[noctxt]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,7 +877,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ABLS
|
p.As = ABLS
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.Pcond = ctxt.Cursym.Text.Link
|
p.Pcond = ctxt.Cursym.Text.Link
|
||||||
|
|
||||||
return p
|
return p
|
||||||
@ -951,7 +899,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
|
|||||||
|
|
||||||
ctxt.Cursym = s
|
ctxt.Cursym = s
|
||||||
|
|
||||||
firstp = ctxt.NewProg()
|
firstp = new(obj.Prog)
|
||||||
lastp = firstp
|
lastp = firstp
|
||||||
xfol(ctxt, s.Text, &lastp)
|
xfol(ctxt, s.Text, &lastp)
|
||||||
lastp.Link = nil
|
lastp.Link = nil
|
||||||
@ -1011,7 +959,7 @@ loop:
|
|||||||
a = int(p.As)
|
a = int(p.As)
|
||||||
if a == AB {
|
if a == AB {
|
||||||
q = p.Pcond
|
q = p.Pcond
|
||||||
if q != nil && q.As != ATEXT {
|
if q != nil && q.As != obj.ATEXT {
|
||||||
p.Mark |= FOLL
|
p.Mark |= FOLL
|
||||||
p = q
|
p = q
|
||||||
if !(p.Mark&FOLL != 0) {
|
if !(p.Mark&FOLL != 0) {
|
||||||
@ -1028,12 +976,12 @@ loop:
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
a = int(q.As)
|
a = int(q.As)
|
||||||
if a == ANOP {
|
if a == obj.ANOP {
|
||||||
i--
|
i--
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if a == AB || (a == ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF {
|
if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
|
||||||
goto copy
|
goto copy
|
||||||
}
|
}
|
||||||
if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
|
if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
|
||||||
@ -1045,7 +993,7 @@ loop:
|
|||||||
|
|
||||||
copy:
|
copy:
|
||||||
for {
|
for {
|
||||||
r = ctxt.NewProg()
|
r = new(obj.Prog)
|
||||||
*r = *p
|
*r = *p
|
||||||
if !(r.Mark&FOLL != 0) {
|
if !(r.Mark&FOLL != 0) {
|
||||||
fmt.Printf("can't happen 1\n")
|
fmt.Printf("can't happen 1\n")
|
||||||
@ -1060,7 +1008,7 @@ loop:
|
|||||||
|
|
||||||
(*last).Link = r
|
(*last).Link = r
|
||||||
*last = r
|
*last = r
|
||||||
if a == AB || (a == ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF {
|
if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.As = ABNE
|
r.As = ABNE
|
||||||
@ -1080,10 +1028,10 @@ loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
a = AB
|
a = AB
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
q.As = int16(a)
|
q.As = int16(a)
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.To.Type = D_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q.To.Offset = p.Pc
|
q.To.Offset = p.Pc
|
||||||
q.Pcond = p
|
q.Pcond = p
|
||||||
p = q
|
p = q
|
||||||
@ -1092,14 +1040,14 @@ loop:
|
|||||||
p.Mark |= FOLL
|
p.Mark |= FOLL
|
||||||
(*last).Link = p
|
(*last).Link = p
|
||||||
*last = p
|
*last = p
|
||||||
if a == AB || (a == ARET && p.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF {
|
if a == AB || (a == obj.ARET && p.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
if a != ABL && a != ABX && p.Link != nil {
|
if a != ABL && a != ABX && p.Link != nil {
|
||||||
q = obj.Brchain(ctxt, p.Link)
|
q = obj.Brchain(ctxt, p.Link)
|
||||||
if a != ATEXT && a != ABCASE {
|
if a != obj.ATEXT && a != ABCASE {
|
||||||
if q != nil && (q.Mark&FOLL != 0) {
|
if q != nil && (q.Mark&FOLL != 0) {
|
||||||
p.As = int16(relinv(a))
|
p.As = int16(relinv(a))
|
||||||
p.Link = p.Pcond
|
p.Link = p.Pcond
|
||||||
@ -1127,46 +1075,16 @@ loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
var Linkarm = obj.LinkArch{
|
var Linkarm = obj.LinkArch{
|
||||||
ByteOrder: binary.LittleEndian,
|
ByteOrder: binary.LittleEndian,
|
||||||
Pconv: Pconv,
|
Pconv: Pconv,
|
||||||
Name: "arm",
|
Name: "arm",
|
||||||
Thechar: '5',
|
Thechar: '5',
|
||||||
Endian: obj.LittleEndian,
|
Endian: obj.LittleEndian,
|
||||||
Addstacksplit: addstacksplit,
|
Preprocess: preprocess,
|
||||||
Assemble: span5,
|
Assemble: span5,
|
||||||
Datasize: datasize,
|
Follow: follow,
|
||||||
Follow: follow,
|
Progedit: progedit,
|
||||||
Iscall: iscall,
|
Minlc: 4,
|
||||||
Isdata: isdata,
|
Ptrsize: 4,
|
||||||
Prg: prg,
|
Regsize: 4,
|
||||||
Progedit: progedit,
|
|
||||||
Settextflag: settextflag,
|
|
||||||
Symtype: symtype,
|
|
||||||
Textflag: textflag,
|
|
||||||
Minlc: 4,
|
|
||||||
Ptrsize: 4,
|
|
||||||
Regsize: 4,
|
|
||||||
D_ADDR: D_ADDR,
|
|
||||||
D_AUTO: D_AUTO,
|
|
||||||
D_BRANCH: D_BRANCH,
|
|
||||||
D_CONST: D_CONST,
|
|
||||||
D_EXTERN: D_EXTERN,
|
|
||||||
D_FCONST: D_FCONST,
|
|
||||||
D_NONE: D_NONE,
|
|
||||||
D_PARAM: D_PARAM,
|
|
||||||
D_SCONST: D_SCONST,
|
|
||||||
D_STATIC: D_STATIC,
|
|
||||||
D_OREG: D_OREG,
|
|
||||||
ACALL: ABL,
|
|
||||||
ADATA: ADATA,
|
|
||||||
AEND: AEND,
|
|
||||||
AFUNCDATA: AFUNCDATA,
|
|
||||||
AGLOBL: AGLOBL,
|
|
||||||
AJMP: AB,
|
|
||||||
ANOP: ANOP,
|
|
||||||
APCDATA: APCDATA,
|
|
||||||
ARET: ARET,
|
|
||||||
ATEXT: ATEXT,
|
|
||||||
ATYPE: ATYPE,
|
|
||||||
AUSEFIELD: AUSEFIELD,
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func mangle(file string) {
|
func mangle(file string) {
|
||||||
|
|
||||||
log.Fatalf("%s: mangled input file", file)
|
log.Fatalf("%s: mangled input file", file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ func Symgrow(ctxt *Link, s *LSym, lsiz int64) {
|
|||||||
|
|
||||||
func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
|
func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
|
||||||
off := int32(p.From.Offset)
|
off := int32(p.From.Offset)
|
||||||
siz := int32(ctxt.Arch.Datasize(p))
|
siz := int32(p.From3.Offset)
|
||||||
if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 {
|
if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 {
|
||||||
mangle(pn)
|
mangle(pn)
|
||||||
}
|
}
|
||||||
@ -71,7 +70,7 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
|
|||||||
default:
|
default:
|
||||||
ctxt.Diag("bad data: %P", p)
|
ctxt.Diag("bad data: %P", p)
|
||||||
|
|
||||||
case ctxt.Arch.D_FCONST:
|
case TYPE_FCONST:
|
||||||
switch siz {
|
switch siz {
|
||||||
default:
|
default:
|
||||||
ctxt.Diag("unexpected %d-byte floating point constant", siz)
|
ctxt.Diag("unexpected %d-byte floating point constant", siz)
|
||||||
@ -85,11 +84,11 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
|
|||||||
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt)
|
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ctxt.Arch.D_SCONST:
|
case TYPE_SCONST:
|
||||||
copy(s.P[off:off+siz], p.To.U.Sval)
|
copy(s.P[off:off+siz], p.To.U.Sval)
|
||||||
|
|
||||||
case ctxt.Arch.D_CONST, ctxt.Arch.D_ADDR:
|
case TYPE_CONST, TYPE_ADDR:
|
||||||
if p.To.Sym != nil || int(p.To.Type) == ctxt.Arch.D_ADDR {
|
if p.To.Sym != nil || int(p.To.Type) == TYPE_ADDR {
|
||||||
r := Addrel(s)
|
r := Addrel(s)
|
||||||
r.Off = off
|
r.Off = off
|
||||||
r.Siz = uint8(siz)
|
r.Siz = uint8(siz)
|
||||||
@ -119,7 +118,7 @@ func Addrel(s *LSym) *Reloc {
|
|||||||
return &s.R[len(s.R)-1]
|
return &s.R[len(s.R)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
|
func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = SDATA
|
s.Type = SDATA
|
||||||
}
|
}
|
||||||
@ -147,7 +146,7 @@ func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
|
|||||||
var off int64
|
var off int64
|
||||||
|
|
||||||
off = s.Size
|
off = s.Size
|
||||||
setuintxx(ctxt, s, off, v, int64(wid))
|
Setuintxx(ctxt, s, off, v, int64(wid))
|
||||||
return off
|
return off
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,19 +167,19 @@ func Adduint64(ctxt *Link, s *LSym, v uint64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 {
|
func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 {
|
||||||
return setuintxx(ctxt, s, r, uint64(v), 1)
|
return Setuintxx(ctxt, s, r, uint64(v), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setuint16(ctxt *Link, s *LSym, r int64, v uint16) int64 {
|
func setuint16(ctxt *Link, s *LSym, r int64, v uint16) int64 {
|
||||||
return setuintxx(ctxt, s, r, uint64(v), 2)
|
return Setuintxx(ctxt, s, r, uint64(v), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 {
|
func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 {
|
||||||
return setuintxx(ctxt, s, r, uint64(v), 4)
|
return Setuintxx(ctxt, s, r, uint64(v), 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setuint64(ctxt *Link, s *LSym, r int64, v uint64) int64 {
|
func setuint64(ctxt *Link, s *LSym, r int64, v uint64) int64 {
|
||||||
return setuintxx(ctxt, s, r, v, 8)
|
return Setuintxx(ctxt, s, r, v, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.c from Vita Nuova.
|
// Inferno utils/5c/list.c
|
||||||
|
// http://code.google.com/p/inferno-os/source/browse/utils/5c/list.c
|
||||||
//
|
//
|
||||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -74,5 +75,5 @@ const (
|
|||||||
FUNCDATA_ArgsPointerMaps = 0
|
FUNCDATA_ArgsPointerMaps = 0
|
||||||
FUNCDATA_LocalsPointerMaps = 1
|
FUNCDATA_LocalsPointerMaps = 1
|
||||||
FUNCDATA_DeadValueMaps = 2
|
FUNCDATA_DeadValueMaps = 2
|
||||||
ArgsSizeUnknown = 0x80000000
|
ArgsSizeUnknown = -0x80000000
|
||||||
)
|
)
|
||||||
|
@ -5,12 +5,75 @@
|
|||||||
package obj
|
package obj
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// go-specific code shared across loaders (5l, 6l, 8l).
|
// go-specific code shared across loaders (5l, 6l, 8l).
|
||||||
|
|
||||||
|
var Framepointer_enabled int
|
||||||
|
|
||||||
|
var fieldtrack_enabled int
|
||||||
|
|
||||||
|
var Zprog Prog
|
||||||
|
|
||||||
|
// Toolchain experiments.
|
||||||
|
// These are controlled by the GOEXPERIMENT environment
|
||||||
|
// variable recorded when the toolchain is built.
|
||||||
|
// This list is also known to cmd/gc.
|
||||||
|
var exper = []struct {
|
||||||
|
name string
|
||||||
|
val *int
|
||||||
|
}{
|
||||||
|
struct {
|
||||||
|
name string
|
||||||
|
val *int
|
||||||
|
}{"fieldtrack", &fieldtrack_enabled},
|
||||||
|
struct {
|
||||||
|
name string
|
||||||
|
val *int
|
||||||
|
}{"framepointer", &Framepointer_enabled},
|
||||||
|
}
|
||||||
|
|
||||||
|
func addexp(s string) {
|
||||||
|
var i int
|
||||||
|
|
||||||
|
for i = 0; i < len(exper); i++ {
|
||||||
|
if exper[i].name == s {
|
||||||
|
if exper[i].val != nil {
|
||||||
|
*exper[i].val = 1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("unknown experiment %s\n", s)
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func linksetexp() {
|
||||||
|
for _, f := range strings.Split(goexperiment, ",") {
|
||||||
|
if f != "" {
|
||||||
|
addexp(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func expstring() string {
|
||||||
|
buf := "X"
|
||||||
|
for i := range exper {
|
||||||
|
if *exper[i].val != 0 {
|
||||||
|
buf += "," + exper[i].name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buf == "X" {
|
||||||
|
buf += ",none"
|
||||||
|
}
|
||||||
|
return "X:" + buf[2:]
|
||||||
|
}
|
||||||
|
|
||||||
// replace all "". with pkg.
|
// replace all "". with pkg.
|
||||||
func expandpkg(t0 string, pkg string) string {
|
func expandpkg(t0 string, pkg string) string {
|
||||||
return strings.Replace(t0, `"".`, pkg+".", -1)
|
return strings.Replace(t0, `"".`, pkg+".", -1)
|
||||||
|
@ -30,9 +30,10 @@
|
|||||||
|
|
||||||
package i386
|
package i386
|
||||||
|
|
||||||
|
import "cmd/internal/obj"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AXXX = iota
|
AAAA = obj.A_ARCHSPECIFIC + iota
|
||||||
AAAA
|
|
||||||
AAAD
|
AAAD
|
||||||
AAAM
|
AAAM
|
||||||
AAAS
|
AAAS
|
||||||
@ -62,7 +63,6 @@ const (
|
|||||||
ABTSL
|
ABTSL
|
||||||
ABTSW
|
ABTSW
|
||||||
ABYTE
|
ABYTE
|
||||||
ACALL
|
|
||||||
ACLC
|
ACLC
|
||||||
ACLD
|
ACLD
|
||||||
ACLI
|
ACLI
|
||||||
@ -76,7 +76,6 @@ const (
|
|||||||
ACMPSW
|
ACMPSW
|
||||||
ADAA
|
ADAA
|
||||||
ADAS
|
ADAS
|
||||||
ADATA
|
|
||||||
ADECB
|
ADECB
|
||||||
ADECL
|
ADECL
|
||||||
ADECW
|
ADECW
|
||||||
@ -84,9 +83,6 @@ const (
|
|||||||
ADIVL
|
ADIVL
|
||||||
ADIVW
|
ADIVW
|
||||||
AENTER
|
AENTER
|
||||||
AGLOBL
|
|
||||||
AGOK
|
|
||||||
AHISTORY
|
|
||||||
AHLT
|
AHLT
|
||||||
AIDIVB
|
AIDIVB
|
||||||
AIDIVL
|
AIDIVL
|
||||||
@ -119,7 +115,6 @@ const (
|
|||||||
AJLS
|
AJLS
|
||||||
AJLT
|
AJLT
|
||||||
AJMI
|
AJMI
|
||||||
AJMP
|
|
||||||
AJNE
|
AJNE
|
||||||
AJOC
|
AJOC
|
||||||
AJOS
|
AJOS
|
||||||
@ -159,11 +154,9 @@ const (
|
|||||||
AMULB
|
AMULB
|
||||||
AMULL
|
AMULL
|
||||||
AMULW
|
AMULW
|
||||||
ANAME
|
|
||||||
ANEGB
|
ANEGB
|
||||||
ANEGL
|
ANEGL
|
||||||
ANEGW
|
ANEGW
|
||||||
ANOP
|
|
||||||
ANOTB
|
ANOTB
|
||||||
ANOTL
|
ANOTL
|
||||||
ANOTW
|
ANOTW
|
||||||
@ -197,7 +190,6 @@ const (
|
|||||||
ARCRW
|
ARCRW
|
||||||
AREP
|
AREP
|
||||||
AREPN
|
AREPN
|
||||||
ARET
|
|
||||||
AROLB
|
AROLB
|
||||||
AROLL
|
AROLL
|
||||||
AROLW
|
AROLW
|
||||||
@ -254,7 +246,6 @@ const (
|
|||||||
ATESTB
|
ATESTB
|
||||||
ATESTL
|
ATESTL
|
||||||
ATESTW
|
ATESTW
|
||||||
ATEXT
|
|
||||||
AVERR
|
AVERR
|
||||||
AVERW
|
AVERW
|
||||||
AWAIT
|
AWAIT
|
||||||
@ -367,10 +358,6 @@ const (
|
|||||||
AFXTRACT
|
AFXTRACT
|
||||||
AFYL2X
|
AFYL2X
|
||||||
AFYL2XP1
|
AFYL2XP1
|
||||||
AEND
|
|
||||||
ADYNT_
|
|
||||||
AINIT_
|
|
||||||
ASIGNAME
|
|
||||||
ACMPXCHGB
|
ACMPXCHGB
|
||||||
ACMPXCHGL
|
ACMPXCHGL
|
||||||
ACMPXCHGW
|
ACMPXCHGW
|
||||||
@ -429,7 +416,6 @@ const (
|
|||||||
APREFETCHT2
|
APREFETCHT2
|
||||||
APREFETCHNTA
|
APREFETCHNTA
|
||||||
ABSWAPL
|
ABSWAPL
|
||||||
AUNDEF
|
|
||||||
AADDPD
|
AADDPD
|
||||||
AADDPS
|
AADDPS
|
||||||
AADDSD
|
AADDSD
|
||||||
@ -544,73 +530,53 @@ const (
|
|||||||
AAESENC
|
AAESENC
|
||||||
APINSRD
|
APINSRD
|
||||||
APSHUFB
|
APSHUFB
|
||||||
AUSEFIELD
|
|
||||||
ATYPE
|
|
||||||
AFUNCDATA
|
|
||||||
APCDATA
|
|
||||||
ACHECKNIL
|
|
||||||
AVARDEF
|
|
||||||
AVARKILL
|
|
||||||
ADUFFCOPY
|
|
||||||
ADUFFZERO
|
|
||||||
ALAST
|
ALAST
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
D_AL = 0 + iota
|
REG_NONE = 0
|
||||||
D_CL
|
REG_AL = 0 + 16 + iota - 1
|
||||||
D_DL
|
REG_CL
|
||||||
D_BL
|
REG_DL
|
||||||
D_AH = 4 + iota - 4
|
REG_BL
|
||||||
D_CH
|
REG_AH = 4 + 16 + iota - 5
|
||||||
D_DH
|
REG_CH
|
||||||
D_BH
|
REG_DH
|
||||||
D_AX = 8 + iota - 8
|
REG_BH
|
||||||
D_CX
|
REG_AX = 8 + 16 + iota - 9
|
||||||
D_DX
|
REG_CX
|
||||||
D_BX
|
REG_DX
|
||||||
D_SP
|
REG_BX
|
||||||
D_BP
|
REG_SP
|
||||||
D_SI
|
REG_BP
|
||||||
D_DI
|
REG_SI
|
||||||
D_F0 = 16
|
REG_DI
|
||||||
D_F7 = D_F0 + 7
|
REG_F0 = 16 + 16
|
||||||
D_CS = 24 + iota - 18
|
REG_F7 = REG_F0 + 7 + 16
|
||||||
D_SS
|
REG_CS = 24 + 16 + iota - 19
|
||||||
D_DS
|
REG_SS
|
||||||
D_ES
|
REG_DS
|
||||||
D_FS
|
REG_ES
|
||||||
D_GS
|
REG_FS
|
||||||
D_GDTR
|
REG_GS
|
||||||
D_IDTR
|
REG_GDTR
|
||||||
D_LDTR
|
REG_IDTR
|
||||||
D_MSW
|
REG_LDTR
|
||||||
D_TASK
|
REG_MSW
|
||||||
D_CR = 35
|
REG_TASK
|
||||||
D_DR = 43
|
REG_CR = 35 + 16
|
||||||
D_TR = 51
|
REG_DR = 43 + 16
|
||||||
D_X0 = 59 + iota - 32
|
REG_TR = 51 + 16
|
||||||
D_X1
|
REG_X0 = 59 + 16 + iota - 33
|
||||||
D_X2
|
REG_X1
|
||||||
D_X3
|
REG_X2
|
||||||
D_X4
|
REG_X3
|
||||||
D_X5
|
REG_X4
|
||||||
D_X6
|
REG_X5
|
||||||
D_X7
|
REG_X6
|
||||||
D_TLS = 67
|
REG_X7
|
||||||
D_NONE = 68
|
REG_TLS = 67 + 16
|
||||||
D_BRANCH = 69
|
MAXREG = 68 + 16
|
||||||
D_EXTERN = 70
|
|
||||||
D_STATIC = 71
|
|
||||||
D_AUTO = 72
|
|
||||||
D_PARAM = 73
|
|
||||||
D_CONST = 74
|
|
||||||
D_FCONST = 75
|
|
||||||
D_SCONST = 76
|
|
||||||
D_ADDR = 77 + iota - 50
|
|
||||||
D_INDIR
|
|
||||||
D_CONST2 = D_INDIR + D_INDIR + iota - 52
|
|
||||||
D_LAST
|
|
||||||
T_TYPE = 1 << 0
|
T_TYPE = 1 << 0
|
||||||
T_INDEX = 1 << 1
|
T_INDEX = 1 << 1
|
||||||
T_OFFSET = 1 << 2
|
T_OFFSET = 1 << 2
|
||||||
@ -620,8 +586,8 @@ const (
|
|||||||
T_OFFSET2 = 1 << 6
|
T_OFFSET2 = 1 << 6
|
||||||
T_GOTYPE = 1 << 7
|
T_GOTYPE = 1 << 7
|
||||||
REGARG = -1
|
REGARG = -1
|
||||||
REGRET = D_AX
|
REGRET = REG_AX
|
||||||
FREGRET = D_F0
|
FREGRET = REG_F0
|
||||||
REGSP = D_SP
|
REGSP = REG_SP
|
||||||
REGTMP = D_DI
|
REGTMP = REG_DI
|
||||||
)
|
)
|
||||||
|
@ -4,8 +4,26 @@ package i386
|
|||||||
* this is the ranlib header
|
* this is the ranlib header
|
||||||
*/
|
*/
|
||||||
var Anames = []string{
|
var Anames = []string{
|
||||||
"XXX",
|
"XXX ",
|
||||||
"AAA",
|
"CALL",
|
||||||
|
"CHECKNIL",
|
||||||
|
"DATA",
|
||||||
|
"DUFFCOPY",
|
||||||
|
"DUFFZERO",
|
||||||
|
"END",
|
||||||
|
"FUNCDATA",
|
||||||
|
"GLOBL",
|
||||||
|
"JMP",
|
||||||
|
"NOP",
|
||||||
|
"PCDATA",
|
||||||
|
"RET",
|
||||||
|
"TEXT",
|
||||||
|
"TYPE",
|
||||||
|
"UNDEF",
|
||||||
|
"USEFIELD",
|
||||||
|
"VARDEF",
|
||||||
|
"VARKILL",
|
||||||
|
"AAA ",
|
||||||
"AAD",
|
"AAD",
|
||||||
"AAM",
|
"AAM",
|
||||||
"AAS",
|
"AAS",
|
||||||
@ -35,7 +53,6 @@ var Anames = []string{
|
|||||||
"BTSL",
|
"BTSL",
|
||||||
"BTSW",
|
"BTSW",
|
||||||
"BYTE",
|
"BYTE",
|
||||||
"CALL",
|
|
||||||
"CLC",
|
"CLC",
|
||||||
"CLD",
|
"CLD",
|
||||||
"CLI",
|
"CLI",
|
||||||
@ -49,7 +66,6 @@ var Anames = []string{
|
|||||||
"CMPSW",
|
"CMPSW",
|
||||||
"DAA",
|
"DAA",
|
||||||
"DAS",
|
"DAS",
|
||||||
"DATA",
|
|
||||||
"DECB",
|
"DECB",
|
||||||
"DECL",
|
"DECL",
|
||||||
"DECW",
|
"DECW",
|
||||||
@ -57,9 +73,6 @@ var Anames = []string{
|
|||||||
"DIVL",
|
"DIVL",
|
||||||
"DIVW",
|
"DIVW",
|
||||||
"ENTER",
|
"ENTER",
|
||||||
"GLOBL",
|
|
||||||
"GOK",
|
|
||||||
"HISTORY",
|
|
||||||
"HLT",
|
"HLT",
|
||||||
"IDIVB",
|
"IDIVB",
|
||||||
"IDIVL",
|
"IDIVL",
|
||||||
@ -92,7 +105,6 @@ var Anames = []string{
|
|||||||
"JLS",
|
"JLS",
|
||||||
"JLT",
|
"JLT",
|
||||||
"JMI",
|
"JMI",
|
||||||
"JMP",
|
|
||||||
"JNE",
|
"JNE",
|
||||||
"JOC",
|
"JOC",
|
||||||
"JOS",
|
"JOS",
|
||||||
@ -132,11 +144,9 @@ var Anames = []string{
|
|||||||
"MULB",
|
"MULB",
|
||||||
"MULL",
|
"MULL",
|
||||||
"MULW",
|
"MULW",
|
||||||
"NAME",
|
|
||||||
"NEGB",
|
"NEGB",
|
||||||
"NEGL",
|
"NEGL",
|
||||||
"NEGW",
|
"NEGW",
|
||||||
"NOP",
|
|
||||||
"NOTB",
|
"NOTB",
|
||||||
"NOTL",
|
"NOTL",
|
||||||
"NOTW",
|
"NOTW",
|
||||||
@ -170,7 +180,6 @@ var Anames = []string{
|
|||||||
"RCRW",
|
"RCRW",
|
||||||
"REP",
|
"REP",
|
||||||
"REPN",
|
"REPN",
|
||||||
"RET",
|
|
||||||
"ROLB",
|
"ROLB",
|
||||||
"ROLL",
|
"ROLL",
|
||||||
"ROLW",
|
"ROLW",
|
||||||
@ -227,7 +236,6 @@ var Anames = []string{
|
|||||||
"TESTB",
|
"TESTB",
|
||||||
"TESTL",
|
"TESTL",
|
||||||
"TESTW",
|
"TESTW",
|
||||||
"TEXT",
|
|
||||||
"VERR",
|
"VERR",
|
||||||
"VERW",
|
"VERW",
|
||||||
"WAIT",
|
"WAIT",
|
||||||
@ -340,10 +348,6 @@ var Anames = []string{
|
|||||||
"FXTRACT",
|
"FXTRACT",
|
||||||
"FYL2X",
|
"FYL2X",
|
||||||
"FYL2XP1",
|
"FYL2XP1",
|
||||||
"END",
|
|
||||||
"DYNT_",
|
|
||||||
"INIT_",
|
|
||||||
"SIGNAME",
|
|
||||||
"CMPXCHGB",
|
"CMPXCHGB",
|
||||||
"CMPXCHGL",
|
"CMPXCHGL",
|
||||||
"CMPXCHGW",
|
"CMPXCHGW",
|
||||||
@ -402,7 +406,6 @@ var Anames = []string{
|
|||||||
"PREFETCHT2",
|
"PREFETCHT2",
|
||||||
"PREFETCHNTA",
|
"PREFETCHNTA",
|
||||||
"BSWAPL",
|
"BSWAPL",
|
||||||
"UNDEF",
|
|
||||||
"ADDPD",
|
"ADDPD",
|
||||||
"ADDPS",
|
"ADDPS",
|
||||||
"ADDSD",
|
"ADDSD",
|
||||||
@ -517,68 +520,5 @@ var Anames = []string{
|
|||||||
"AESENC",
|
"AESENC",
|
||||||
"PINSRD",
|
"PINSRD",
|
||||||
"PSHUFB",
|
"PSHUFB",
|
||||||
"USEFIELD",
|
|
||||||
"TYPE",
|
|
||||||
"FUNCDATA",
|
|
||||||
"PCDATA",
|
|
||||||
"CHECKNIL",
|
|
||||||
"VARDEF",
|
|
||||||
"VARKILL",
|
|
||||||
"DUFFCOPY",
|
|
||||||
"DUFFZERO",
|
|
||||||
"LAST",
|
"LAST",
|
||||||
}
|
}
|
||||||
|
|
||||||
var dnames8 = []string{
|
|
||||||
D_AL: "AL",
|
|
||||||
D_CL: "CL",
|
|
||||||
D_DL: "DL",
|
|
||||||
D_BL: "BL",
|
|
||||||
D_AH: "AH",
|
|
||||||
D_CH: "CH",
|
|
||||||
D_DH: "DH",
|
|
||||||
D_BH: "BH",
|
|
||||||
D_AX: "AX",
|
|
||||||
D_CX: "CX",
|
|
||||||
D_DX: "DX",
|
|
||||||
D_BX: "BX",
|
|
||||||
D_SP: "SP",
|
|
||||||
D_BP: "BP",
|
|
||||||
D_SI: "SI",
|
|
||||||
D_DI: "DI",
|
|
||||||
D_F0: "F0",
|
|
||||||
D_CS: "CS",
|
|
||||||
D_SS: "SS",
|
|
||||||
D_DS: "DS",
|
|
||||||
D_ES: "ES",
|
|
||||||
D_FS: "FS",
|
|
||||||
D_GS: "GS",
|
|
||||||
D_GDTR: "GDTR",
|
|
||||||
D_IDTR: "IDTR",
|
|
||||||
D_LDTR: "LDTR",
|
|
||||||
D_MSW: "MSW",
|
|
||||||
D_TASK: "TASK",
|
|
||||||
D_CR: "CR",
|
|
||||||
D_DR: "DR",
|
|
||||||
D_TR: "TR",
|
|
||||||
D_X0: "X0",
|
|
||||||
D_X1: "X1",
|
|
||||||
D_X2: "X2",
|
|
||||||
D_X3: "X3",
|
|
||||||
D_X4: "X4",
|
|
||||||
D_X5: "X5",
|
|
||||||
D_X6: "X6",
|
|
||||||
D_X7: "X7",
|
|
||||||
D_TLS: "TLS",
|
|
||||||
D_NONE: "NONE",
|
|
||||||
D_BRANCH: "BRANCH",
|
|
||||||
D_EXTERN: "EXTERN",
|
|
||||||
D_STATIC: "STATIC",
|
|
||||||
D_AUTO: "AUTO",
|
|
||||||
D_PARAM: "PARAM",
|
|
||||||
D_CONST: "CONST",
|
|
||||||
D_FCONST: "FCONST",
|
|
||||||
D_SCONST: "SCONST",
|
|
||||||
D_ADDR: "ADDR",
|
|
||||||
D_INDIR: "INDIR",
|
|
||||||
}
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -46,16 +46,16 @@ func Pconv(p *obj.Prog) string {
|
|||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ADATA:
|
case obj.ADATA:
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
|
||||||
|
|
||||||
case ATEXT:
|
case obj.ATEXT:
|
||||||
if p.From.Scale != 0 {
|
if p.From3.Offset != 0 {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, fmtLong, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
||||||
|
|
||||||
default:
|
default:
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
||||||
@ -78,45 +78,34 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
|
|||||||
var s string
|
var s string
|
||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
var i int
|
switch a.Type {
|
||||||
|
|
||||||
i = int(a.Type)
|
|
||||||
|
|
||||||
if flag&fmtLong != 0 /*untyped*/ {
|
|
||||||
if i == D_CONST2 {
|
|
||||||
str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// ATEXT dst is not constant
|
|
||||||
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
|
|
||||||
}
|
|
||||||
|
|
||||||
goto brk
|
|
||||||
}
|
|
||||||
|
|
||||||
if i >= D_INDIR {
|
|
||||||
if a.Offset != 0 {
|
|
||||||
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR))
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR))
|
|
||||||
}
|
|
||||||
goto brk
|
|
||||||
}
|
|
||||||
|
|
||||||
switch i {
|
|
||||||
default:
|
default:
|
||||||
if a.Offset != 0 {
|
str = fmt.Sprintf("type=%d", a.Type)
|
||||||
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("%v", Rconv(i))
|
case obj.TYPE_NONE:
|
||||||
}
|
|
||||||
|
|
||||||
case D_NONE:
|
|
||||||
str = ""
|
str = ""
|
||||||
|
|
||||||
case D_BRANCH:
|
// TODO(rsc): This special case is for instructions like
|
||||||
|
// PINSRQ CX,$1,X6
|
||||||
|
// where the $1 is included in the p->to Addr.
|
||||||
|
// Move into a new field.
|
||||||
|
case obj.TYPE_REG:
|
||||||
|
if a.Offset != 0 {
|
||||||
|
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg)))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
|
||||||
|
|
||||||
|
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
|
||||||
|
// SHRQ $32(DX*0), AX
|
||||||
|
// Remove.
|
||||||
|
if a.Index != REG_NONE {
|
||||||
|
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||||
|
str += s
|
||||||
|
}
|
||||||
|
|
||||||
|
case obj.TYPE_BRANCH:
|
||||||
if a.Sym != nil {
|
if a.Sym != nil {
|
||||||
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
|
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
|
||||||
} else if p != nil && p.Pcond != nil {
|
} else if p != nil && p.Pcond != nil {
|
||||||
@ -124,69 +113,85 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
|
|||||||
} else if a.U.Branch != nil {
|
} else if a.U.Branch != nil {
|
||||||
str = fmt.Sprintf("%d", a.U.Branch.Pc)
|
str = fmt.Sprintf("%d", a.U.Branch.Pc)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%d(PC)", a.Offset)
|
str = fmt.Sprintf("%d(PC)", a.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_EXTERN:
|
case obj.TYPE_MEM:
|
||||||
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
|
switch a.Name {
|
||||||
|
default:
|
||||||
|
str = fmt.Sprintf("name=%d", a.Name)
|
||||||
|
|
||||||
case D_STATIC:
|
case obj.NAME_NONE:
|
||||||
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
|
if a.Offset != 0 {
|
||||||
|
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg)))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
|
||||||
|
}
|
||||||
|
|
||||||
case D_AUTO:
|
case obj.NAME_EXTERN:
|
||||||
if a.Sym != nil {
|
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
|
||||||
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("%d(SP)", a.Offset)
|
case obj.NAME_STATIC:
|
||||||
|
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
|
||||||
|
|
||||||
|
case obj.NAME_AUTO:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%d(SP)", a.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
case obj.NAME_PARAM:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%d(FP)", a.Offset)
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_PARAM:
|
if a.Index != REG_NONE {
|
||||||
if a.Sym != nil {
|
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||||
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
|
str += s
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("%d(FP)", a.Offset)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_CONST:
|
case obj.TYPE_CONST:
|
||||||
str = fmt.Sprintf("$%d", a.Offset)
|
str = fmt.Sprintf("$%d", a.Offset)
|
||||||
|
|
||||||
case D_CONST2:
|
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
|
||||||
if !(flag&fmtLong != 0 /*untyped*/) {
|
// SHRQ $32(DX*0), AX
|
||||||
// D_CONST2 outside of ATEXT should not happen
|
// Remove.
|
||||||
str = fmt.Sprintf("!!$%d-%d", a.Offset, a.Offset2)
|
if a.Index != REG_NONE {
|
||||||
|
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||||
|
str += s
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_FCONST:
|
case obj.TYPE_TEXTSIZE:
|
||||||
|
if a.U.Argsize == obj.ArgsSizeUnknown {
|
||||||
|
str = fmt.Sprintf("$%d", a.Offset)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
case obj.TYPE_FCONST:
|
||||||
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
|
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
|
||||||
|
|
||||||
case D_SCONST:
|
case obj.TYPE_SCONST:
|
||||||
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
||||||
|
|
||||||
case D_ADDR:
|
case obj.TYPE_ADDR:
|
||||||
a.Type = int16(a.Index)
|
a.Type = obj.TYPE_MEM
|
||||||
a.Index = D_NONE
|
|
||||||
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
|
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
|
||||||
a.Index = uint8(a.Type)
|
a.Type = obj.TYPE_ADDR
|
||||||
a.Type = D_ADDR
|
break
|
||||||
goto conv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
brk:
|
|
||||||
if a.Index != D_NONE {
|
|
||||||
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
|
||||||
str += s
|
|
||||||
}
|
|
||||||
|
|
||||||
conv:
|
|
||||||
fp += str
|
fp += str
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
var Register = []string{
|
var Register = []string{
|
||||||
"AL", /* [D_AL] */
|
"AL", /* [REG_AL] */
|
||||||
"CL",
|
"CL",
|
||||||
"DL",
|
"DL",
|
||||||
"BL",
|
"BL",
|
||||||
@ -194,7 +199,7 @@ var Register = []string{
|
|||||||
"CH",
|
"CH",
|
||||||
"DH",
|
"DH",
|
||||||
"BH",
|
"BH",
|
||||||
"AX", /* [D_AX] */
|
"AX", /* [REG_AX] */
|
||||||
"CX",
|
"CX",
|
||||||
"DX",
|
"DX",
|
||||||
"BX",
|
"BX",
|
||||||
@ -202,7 +207,7 @@ var Register = []string{
|
|||||||
"BP",
|
"BP",
|
||||||
"SI",
|
"SI",
|
||||||
"DI",
|
"DI",
|
||||||
"F0", /* [D_F0] */
|
"F0", /* [REG_F0] */
|
||||||
"F1",
|
"F1",
|
||||||
"F2",
|
"F2",
|
||||||
"F3",
|
"F3",
|
||||||
@ -210,18 +215,18 @@ var Register = []string{
|
|||||||
"F5",
|
"F5",
|
||||||
"F6",
|
"F6",
|
||||||
"F7",
|
"F7",
|
||||||
"CS", /* [D_CS] */
|
"CS", /* [REG_CS] */
|
||||||
"SS",
|
"SS",
|
||||||
"DS",
|
"DS",
|
||||||
"ES",
|
"ES",
|
||||||
"FS",
|
"FS",
|
||||||
"GS",
|
"GS",
|
||||||
"GDTR", /* [D_GDTR] */
|
"GDTR", /* [REG_GDTR] */
|
||||||
"IDTR", /* [D_IDTR] */
|
"IDTR", /* [REG_IDTR] */
|
||||||
"LDTR", /* [D_LDTR] */
|
"LDTR", /* [REG_LDTR] */
|
||||||
"MSW", /* [D_MSW] */
|
"MSW", /* [REG_MSW] */
|
||||||
"TASK", /* [D_TASK] */
|
"TASK", /* [REG_TASK] */
|
||||||
"CR0", /* [D_CR] */
|
"CR0", /* [REG_CR] */
|
||||||
"CR1",
|
"CR1",
|
||||||
"CR2",
|
"CR2",
|
||||||
"CR3",
|
"CR3",
|
||||||
@ -229,7 +234,7 @@ var Register = []string{
|
|||||||
"CR5",
|
"CR5",
|
||||||
"CR6",
|
"CR6",
|
||||||
"CR7",
|
"CR7",
|
||||||
"DR0", /* [D_DR] */
|
"DR0", /* [REG_DR] */
|
||||||
"DR1",
|
"DR1",
|
||||||
"DR2",
|
"DR2",
|
||||||
"DR3",
|
"DR3",
|
||||||
@ -237,7 +242,7 @@ var Register = []string{
|
|||||||
"DR5",
|
"DR5",
|
||||||
"DR6",
|
"DR6",
|
||||||
"DR7",
|
"DR7",
|
||||||
"TR0", /* [D_TR] */
|
"TR0", /* [REG_TR] */
|
||||||
"TR1",
|
"TR1",
|
||||||
"TR2",
|
"TR2",
|
||||||
"TR3",
|
"TR3",
|
||||||
@ -245,7 +250,7 @@ var Register = []string{
|
|||||||
"TR5",
|
"TR5",
|
||||||
"TR6",
|
"TR6",
|
||||||
"TR7",
|
"TR7",
|
||||||
"X0", /* [D_X0] */
|
"X0", /* [REG_X0] */
|
||||||
"X1",
|
"X1",
|
||||||
"X2",
|
"X2",
|
||||||
"X3",
|
"X3",
|
||||||
@ -253,18 +258,21 @@ var Register = []string{
|
|||||||
"X5",
|
"X5",
|
||||||
"X6",
|
"X6",
|
||||||
"X7",
|
"X7",
|
||||||
"TLS", /* [D_TLS] */
|
"TLS", /* [REG_TLS] */
|
||||||
"NONE", /* [D_NONE] */
|
"MAXREG", /* [MAXREG] */
|
||||||
}
|
}
|
||||||
|
|
||||||
func Rconv(r int) string {
|
func Rconv(r int) string {
|
||||||
var str string
|
var str string
|
||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
if r >= D_AL && r <= D_NONE {
|
if r == REG_NONE {
|
||||||
str = fmt.Sprintf("%s", Register[r-D_AL])
|
fp += "NONE"
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if r >= REG_AL && r-REG_AL < len(Register) {
|
||||||
|
str = fmt.Sprintf("%s", Register[r-REG_AL])
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("gok(%d)", r)
|
str = fmt.Sprintf("gok(%d)", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,51 +38,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
var zprg = obj.Prog{
|
|
||||||
Back: 2,
|
|
||||||
As: AGOK,
|
|
||||||
From: obj.Addr{
|
|
||||||
Type: D_NONE,
|
|
||||||
Index: D_NONE,
|
|
||||||
Scale: 1,
|
|
||||||
},
|
|
||||||
To: obj.Addr{
|
|
||||||
Type: D_NONE,
|
|
||||||
Index: D_NONE,
|
|
||||||
Scale: 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func symtype(a *obj.Addr) int {
|
|
||||||
var t int
|
|
||||||
|
|
||||||
t = int(a.Type)
|
|
||||||
if t == D_ADDR {
|
|
||||||
t = int(a.Index)
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
func isdata(p *obj.Prog) bool {
|
|
||||||
return p.As == ADATA || p.As == AGLOBL
|
|
||||||
}
|
|
||||||
|
|
||||||
func iscall(p *obj.Prog) bool {
|
|
||||||
return p.As == ACALL
|
|
||||||
}
|
|
||||||
|
|
||||||
func datasize(p *obj.Prog) int {
|
|
||||||
return int(p.From.Scale)
|
|
||||||
}
|
|
||||||
|
|
||||||
func textflag(p *obj.Prog) int {
|
|
||||||
return int(p.From.Scale)
|
|
||||||
}
|
|
||||||
|
|
||||||
func settextflag(p *obj.Prog, f int) {
|
|
||||||
p.From.Scale = int8(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func canuselocaltls(ctxt *obj.Link) int {
|
func canuselocaltls(ctxt *obj.Link) int {
|
||||||
switch ctxt.Headtype {
|
switch ctxt.Headtype {
|
||||||
case obj.Hlinux,
|
case obj.Hlinux,
|
||||||
@ -102,7 +57,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
|
|
||||||
// See obj6.c for discussion of TLS.
|
// See obj6.c for discussion of TLS.
|
||||||
if canuselocaltls(ctxt) != 0 {
|
if canuselocaltls(ctxt) != 0 {
|
||||||
|
|
||||||
// Reduce TLS initial exec model to TLS local exec model.
|
// Reduce TLS initial exec model to TLS local exec model.
|
||||||
// Sequences like
|
// Sequences like
|
||||||
// MOVL TLS, BX
|
// MOVL TLS, BX
|
||||||
@ -110,26 +64,26 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
// become
|
// become
|
||||||
// NOP
|
// NOP
|
||||||
// ... off(TLS) ...
|
// ... off(TLS) ...
|
||||||
if p.As == AMOVL && p.From.Type == D_TLS && D_AX <= p.To.Type && p.To.Type <= D_DI {
|
if p.As == AMOVL && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI {
|
||||||
|
p.As = obj.ANOP
|
||||||
p.As = ANOP
|
p.From.Type = obj.TYPE_NONE
|
||||||
p.From.Type = D_NONE
|
p.To.Type = obj.TYPE_NONE
|
||||||
p.To.Type = D_NONE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.From.Index == D_TLS && D_INDIR+D_AX <= p.From.Type && p.From.Type <= D_INDIR+D_DI {
|
if p.From.Type == obj.TYPE_MEM && p.From.Index == REG_TLS && REG_AX <= p.From.Reg && p.From.Reg <= REG_DI {
|
||||||
p.From.Type = D_INDIR + D_TLS
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_TLS
|
||||||
p.From.Scale = 0
|
p.From.Scale = 0
|
||||||
p.From.Index = D_NONE
|
p.From.Index = REG_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.To.Index == D_TLS && D_INDIR+D_AX <= p.To.Type && p.To.Type <= D_INDIR+D_DI {
|
if p.To.Type == obj.TYPE_MEM && p.To.Index == REG_TLS && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI {
|
||||||
p.To.Type = D_INDIR + D_TLS
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
p.To.Reg = REG_TLS
|
||||||
p.To.Scale = 0
|
p.To.Scale = 0
|
||||||
p.To.Index = D_NONE
|
p.To.Index = REG_NONE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load.
|
// As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load.
|
||||||
// The instruction
|
// The instruction
|
||||||
// MOVL off(TLS), BX
|
// MOVL off(TLS), BX
|
||||||
@ -137,59 +91,52 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
// MOVL TLS, BX
|
// MOVL TLS, BX
|
||||||
// MOVL off(BX)(TLS*1), BX
|
// MOVL off(BX)(TLS*1), BX
|
||||||
// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
|
// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
|
||||||
if p.As == AMOVL && p.From.Type == D_INDIR+D_TLS && D_AX <= p.To.Type && p.To.Type <= D_DI {
|
if p.As == AMOVL && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI {
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, p)
|
q = obj.Appendp(ctxt, p)
|
||||||
q.As = p.As
|
q.As = p.As
|
||||||
q.From = p.From
|
q.From.Type = obj.TYPE_MEM
|
||||||
q.From.Type = D_INDIR + p.To.Type
|
q.From.Reg = p.To.Reg
|
||||||
q.From.Index = D_TLS
|
q.From.Index = REG_TLS
|
||||||
q.From.Scale = 2 // TODO: use 1
|
q.From.Scale = 2 // TODO: use 1
|
||||||
q.To = p.To
|
q.To = p.To
|
||||||
p.From.Type = D_TLS
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Index = D_NONE
|
p.From.Reg = REG_TLS
|
||||||
|
p.From.Index = REG_NONE
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove.
|
// TODO: Remove.
|
||||||
if ctxt.Headtype == obj.Hplan9 {
|
if ctxt.Headtype == obj.Hplan9 {
|
||||||
|
if p.From.Scale == 1 && p.From.Index == REG_TLS {
|
||||||
if p.From.Scale == 1 && p.From.Index == D_TLS {
|
|
||||||
p.From.Scale = 2
|
p.From.Scale = 2
|
||||||
}
|
}
|
||||||
if p.To.Scale == 1 && p.To.Index == D_TLS {
|
if p.To.Scale == 1 && p.To.Index == REG_TLS {
|
||||||
p.To.Scale = 2
|
p.To.Scale = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite CALL/JMP/RET to symbol as D_BRANCH.
|
// Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
case obj.ACALL,
|
||||||
case ACALL,
|
obj.AJMP,
|
||||||
AJMP,
|
obj.ARET:
|
||||||
ARET:
|
if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil {
|
||||||
if (p.To.Type == D_EXTERN || p.To.Type == D_STATIC) && p.To.Sym != nil {
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.To.Type = D_BRANCH
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite float constants to values stored in memory.
|
// Rewrite float constants to values stored in memory.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
|
||||||
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
|
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
|
||||||
case AMOVSS:
|
case AMOVSS:
|
||||||
if p.From.Type == D_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
|
|
||||||
if p.From.U.Dval == 0 {
|
if p.From.U.Dval == 0 {
|
||||||
if p.To.Type >= D_X0 {
|
if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 {
|
||||||
if p.To.Type <= D_X7 {
|
p.As = AXORPS
|
||||||
p.As = AXORPS
|
p.From = p.To
|
||||||
p.From.Type = p.To.Type
|
break
|
||||||
p.From.Index = p.To.Index
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,8 +159,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
ADIVSS,
|
ADIVSS,
|
||||||
ACOMISS,
|
ACOMISS,
|
||||||
AUCOMISS:
|
AUCOMISS:
|
||||||
if p.From.Type == D_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
|
|
||||||
var i32 uint32
|
var i32 uint32
|
||||||
var f32 float32
|
var f32 float32
|
||||||
f32 = float32(p.From.U.Dval)
|
f32 = float32(p.From.U.Dval)
|
||||||
@ -226,23 +172,20 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
s.Reachable = 0
|
s.Reachable = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
p.From.Type = D_EXTERN
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Name = obj.NAME_EXTERN
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
|
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
|
||||||
case AMOVSD:
|
case AMOVSD:
|
||||||
if p.From.Type == D_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
|
|
||||||
if p.From.U.Dval == 0 {
|
if p.From.U.Dval == 0 {
|
||||||
if p.To.Type >= D_X0 {
|
if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 {
|
||||||
if p.To.Type <= D_X7 {
|
p.As = AXORPS
|
||||||
p.As = AXORPS
|
p.From = p.To
|
||||||
p.From.Type = p.To.Type
|
break
|
||||||
p.From.Index = p.To.Index
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,8 +208,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
ADIVSD,
|
ADIVSD,
|
||||||
ACOMISD,
|
ACOMISD,
|
||||||
AUCOMISD:
|
AUCOMISD:
|
||||||
if p.From.Type == D_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
|
|
||||||
var i64 uint64
|
var i64 uint64
|
||||||
i64 = math.Float64bits(p.From.U.Dval)
|
i64 = math.Float64bits(p.From.U.Dval)
|
||||||
literal = fmt.Sprintf("$f64.%016x", i64)
|
literal = fmt.Sprintf("$f64.%016x", i64)
|
||||||
@ -277,7 +219,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
s.Reachable = 0
|
s.Reachable = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
p.From.Type = D_EXTERN
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Name = obj.NAME_EXTERN
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
}
|
}
|
||||||
@ -286,12 +229,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func prg() *obj.Prog {
|
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
p := zprg
|
|
||||||
return &p
|
|
||||||
}
|
|
||||||
|
|
||||||
func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|
||||||
var p *obj.Prog
|
var p *obj.Prog
|
||||||
var q *obj.Prog
|
var q *obj.Prog
|
||||||
var p1 *obj.Prog
|
var p1 *obj.Prog
|
||||||
@ -322,37 +260,35 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cursym.Locals = autoffset
|
cursym.Locals = autoffset
|
||||||
cursym.Args = p.To.Offset2
|
cursym.Args = p.To.U.Argsize
|
||||||
|
|
||||||
q = nil
|
q = nil
|
||||||
|
|
||||||
if !(p.From.Scale&obj.NOSPLIT != 0) || (p.From.Scale&obj.WRAPPER != 0) {
|
if !(p.From3.Offset&obj.NOSPLIT != 0) || (p.From3.Offset&obj.WRAPPER != 0) {
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p = load_g_cx(ctxt, p) // load g into CX
|
p = load_g_cx(ctxt, p) // load g into CX
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(cursym.Text.From.Scale&obj.NOSPLIT != 0) {
|
if !(cursym.Text.From3.Offset&obj.NOSPLIT != 0) {
|
||||||
p = stacksplit(ctxt, p, autoffset, bool2int(!(cursym.Text.From.Scale&obj.NEEDCTXT != 0)), &q) // emit split check
|
p = stacksplit(ctxt, p, autoffset, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0)), &q) // emit split check
|
||||||
}
|
}
|
||||||
|
|
||||||
if autoffset != 0 {
|
if autoffset != 0 {
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AADJSP
|
p.As = AADJSP
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(autoffset)
|
p.From.Offset = int64(autoffset)
|
||||||
p.Spadj = autoffset
|
p.Spadj = autoffset
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// zero-byte stack adjustment.
|
// zero-byte stack adjustment.
|
||||||
// Insert a fake non-zero adjustment so that stkcheck can
|
// Insert a fake non-zero adjustment so that stkcheck can
|
||||||
// recognize the end of the stack-splitting prolog.
|
// recognize the end of the stack-splitting prolog.
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ANOP
|
p.As = obj.ANOP
|
||||||
p.Spadj = int32(-ctxt.Arch.Ptrsize)
|
p.Spadj = int32(-ctxt.Arch.Ptrsize)
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ANOP
|
p.As = obj.ANOP
|
||||||
p.Spadj = int32(ctxt.Arch.Ptrsize)
|
p.Spadj = int32(ctxt.Arch.Ptrsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,7 +297,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
deltasp = autoffset
|
deltasp = autoffset
|
||||||
|
|
||||||
if cursym.Text.From.Scale&obj.WRAPPER != 0 {
|
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||||
//
|
//
|
||||||
// MOVL g_panic(CX), BX
|
// MOVL g_panic(CX), BX
|
||||||
@ -380,71 +316,85 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
p.From.Type = D_INDIR + D_CX
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_CX
|
||||||
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
|
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
|
||||||
p.To.Type = D_BX
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_BX
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ATESTL
|
p.As = ATESTL
|
||||||
p.From.Type = D_BX
|
p.From.Type = obj.TYPE_REG
|
||||||
p.To.Type = D_BX
|
p.From.Reg = REG_BX
|
||||||
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_BX
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJEQ
|
p.As = AJEQ
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p1 = p
|
p1 = p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ALEAL
|
p.As = ALEAL
|
||||||
p.From.Type = D_INDIR + D_SP
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_SP
|
||||||
p.From.Offset = int64(autoffset) + 4
|
p.From.Offset = int64(autoffset) + 4
|
||||||
p.To.Type = D_DI
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_DI
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMPL
|
p.As = ACMPL
|
||||||
p.From.Type = D_INDIR + D_BX
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_BX
|
||||||
p.From.Offset = 0 // Panic.argp
|
p.From.Offset = 0 // Panic.argp
|
||||||
p.To.Type = D_DI
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_DI
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJNE
|
p.As = AJNE
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p2 = p
|
p2 = p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
p.From.Type = D_SP
|
p.From.Type = obj.TYPE_REG
|
||||||
p.To.Type = D_INDIR + D_BX
|
p.From.Reg = REG_SP
|
||||||
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
p.To.Reg = REG_BX
|
||||||
p.To.Offset = 0 // Panic.argp
|
p.To.Offset = 0 // Panic.argp
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ANOP
|
p.As = obj.ANOP
|
||||||
p1.Pcond = p
|
p1.Pcond = p
|
||||||
p2.Pcond = p
|
p2.Pcond = p
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt.Debugzerostack != 0 && autoffset != 0 && !(cursym.Text.From.Scale&obj.NOSPLIT != 0) {
|
if ctxt.Debugzerostack != 0 && autoffset != 0 && !(cursym.Text.From3.Offset&obj.NOSPLIT != 0) {
|
||||||
// 8l -Z means zero the stack frame on entry.
|
// 8l -Z means zero the stack frame on entry.
|
||||||
// This slows down function calls but can help avoid
|
// This slows down function calls but can help avoid
|
||||||
// false positives in garbage collection.
|
// false positives in garbage collection.
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
p.From.Type = D_SP
|
p.From.Type = obj.TYPE_REG
|
||||||
p.To.Type = D_DI
|
p.From.Reg = REG_SP
|
||||||
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_DI
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(autoffset) / 4
|
p.From.Offset = int64(autoffset) / 4
|
||||||
p.To.Type = D_CX
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_CX
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
p.To.Type = D_AX
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_AX
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AREP
|
p.As = AREP
|
||||||
@ -454,18 +404,18 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for ; p != nil; p = p.Link {
|
for ; p != nil; p = p.Link {
|
||||||
a = int(p.From.Type)
|
a = int(p.From.Name)
|
||||||
if a == D_AUTO {
|
if a == obj.NAME_AUTO {
|
||||||
p.From.Offset += int64(deltasp)
|
p.From.Offset += int64(deltasp)
|
||||||
}
|
}
|
||||||
if a == D_PARAM {
|
if a == obj.NAME_PARAM {
|
||||||
p.From.Offset += int64(deltasp) + 4
|
p.From.Offset += int64(deltasp) + 4
|
||||||
}
|
}
|
||||||
a = int(p.To.Type)
|
a = int(p.To.Name)
|
||||||
if a == D_AUTO {
|
if a == obj.NAME_AUTO {
|
||||||
p.To.Offset += int64(deltasp)
|
p.To.Offset += int64(deltasp)
|
||||||
}
|
}
|
||||||
if a == D_PARAM {
|
if a == obj.NAME_PARAM {
|
||||||
p.To.Offset += int64(deltasp) + 4
|
p.To.Offset += int64(deltasp) + 4
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,7 +447,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
p.Spadj = -2
|
p.Spadj = -2
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case ARET:
|
case obj.ARET:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,11 +457,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
if autoffset != 0 {
|
if autoffset != 0 {
|
||||||
p.As = AADJSP
|
p.As = AADJSP
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(-autoffset)
|
p.From.Offset = int64(-autoffset)
|
||||||
p.Spadj = -autoffset
|
p.Spadj = -autoffset
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ARET
|
p.As = obj.ARET
|
||||||
|
|
||||||
// If there are instructions following
|
// If there are instructions following
|
||||||
// this ARET, they come from a branch
|
// this ARET, they come from a branch
|
||||||
@ -521,7 +471,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if p.To.Sym != nil { // retjmp
|
if p.To.Sym != nil { // retjmp
|
||||||
p.As = AJMP
|
p.As = obj.AJMP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -532,13 +482,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
// prologue (caller must call appendp first) and in the epilogue.
|
// prologue (caller must call appendp first) and in the epilogue.
|
||||||
// Returns last new instruction.
|
// Returns last new instruction.
|
||||||
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||||
|
|
||||||
var next *obj.Prog
|
var next *obj.Prog
|
||||||
|
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
p.From.Type = D_INDIR + D_TLS
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_TLS
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
p.To.Type = D_CX
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_CX
|
||||||
|
|
||||||
next = p.Link
|
next = p.Link
|
||||||
progedit(ctxt, p)
|
progedit(ctxt, p)
|
||||||
@ -546,7 +497,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
|||||||
p = p.Link
|
p = p.Link
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.From.Index == D_TLS {
|
if p.From.Index == REG_TLS {
|
||||||
p.From.Scale = 2
|
p.From.Scale = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,7 +511,6 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
|||||||
// On return, *jmpok is the instruction that should jump
|
// On return, *jmpok is the instruction that should jump
|
||||||
// to the stack frame allocation if no split is needed.
|
// to the stack frame allocation if no split is needed.
|
||||||
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok **obj.Prog) *obj.Prog {
|
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok **obj.Prog) *obj.Prog {
|
||||||
|
|
||||||
var q *obj.Prog
|
var q *obj.Prog
|
||||||
var q1 *obj.Prog
|
var q1 *obj.Prog
|
||||||
|
|
||||||
@ -573,23 +523,25 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ACMPL
|
p.As = ACMPL
|
||||||
p.From.Type = D_INDIR + D_CX
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_CX
|
||||||
p.From.Offset = 4
|
p.From.Offset = 4
|
||||||
p.To.Type = D_SP
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_SP
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJCC
|
p.As = AJCC
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.To.Offset = 4
|
p.To.Offset = 4
|
||||||
q1 = p
|
q1 = p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AINT
|
p.As = AINT
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = 3
|
p.From.Offset = 3
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ANOP
|
p.As = obj.ANOP
|
||||||
q1.Pcond = p
|
q1.Pcond = p
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,8 +553,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ACMPL
|
p.As = ACMPL
|
||||||
p.From.Type = D_SP
|
p.From.Type = obj.TYPE_REG
|
||||||
p.To.Type = D_INDIR + D_CX
|
p.From.Reg = REG_SP
|
||||||
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
p.To.Reg = REG_CX
|
||||||
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
||||||
if ctxt.Cursym.Cfunc != 0 {
|
if ctxt.Cursym.Cfunc != 0 {
|
||||||
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
||||||
@ -614,20 +568,23 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ALEAL
|
p.As = ALEAL
|
||||||
p.From.Type = D_INDIR + D_SP
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_SP
|
||||||
p.From.Offset = -(int64(framesize) - obj.StackSmall)
|
p.From.Offset = -(int64(framesize) - obj.StackSmall)
|
||||||
p.To.Type = D_AX
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_AX
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMPL
|
p.As = ACMPL
|
||||||
p.From.Type = D_AX
|
p.From.Type = obj.TYPE_REG
|
||||||
p.To.Type = D_INDIR + D_CX
|
p.From.Reg = REG_AX
|
||||||
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
p.To.Reg = REG_CX
|
||||||
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
||||||
if ctxt.Cursym.Cfunc != 0 {
|
if ctxt.Cursym.Cfunc != 0 {
|
||||||
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Such a large stack we need to protect against wraparound
|
// Such a large stack we need to protect against wraparound
|
||||||
// if SP is close to zero.
|
// if SP is close to zero.
|
||||||
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
|
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
|
||||||
@ -645,41 +602,49 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
p.From.Type = D_INDIR + D_CX
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_CX
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
||||||
if ctxt.Cursym.Cfunc != 0 {
|
if ctxt.Cursym.Cfunc != 0 {
|
||||||
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
||||||
}
|
}
|
||||||
p.To.Type = D_SI
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_SI
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMPL
|
p.As = ACMPL
|
||||||
p.From.Type = D_SI
|
p.From.Type = obj.TYPE_REG
|
||||||
p.To.Type = D_CONST
|
p.From.Reg = REG_SI
|
||||||
|
p.To.Type = obj.TYPE_CONST
|
||||||
p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
|
p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJEQ
|
p.As = AJEQ
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
q1 = p
|
q1 = p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ALEAL
|
p.As = ALEAL
|
||||||
p.From.Type = D_INDIR + D_SP
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = REG_SP
|
||||||
p.From.Offset = obj.StackGuard
|
p.From.Offset = obj.StackGuard
|
||||||
p.To.Type = D_AX
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_AX
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ASUBL
|
p.As = ASUBL
|
||||||
p.From.Type = D_SI
|
p.From.Type = obj.TYPE_REG
|
||||||
|
p.From.Reg = REG_SI
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
p.To.Type = D_AX
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_AX
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMPL
|
p.As = ACMPL
|
||||||
p.From.Type = D_AX
|
p.From.Type = obj.TYPE_REG
|
||||||
p.To.Type = D_CONST
|
p.From.Reg = REG_AX
|
||||||
|
p.To.Type = obj.TYPE_CONST
|
||||||
p.To.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
|
p.To.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,23 +652,22 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AJHI
|
p.As = AJHI
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.To.Offset = 4
|
p.To.Offset = 4
|
||||||
q = p
|
q = p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACALL
|
p.As = obj.ACALL
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
if ctxt.Cursym.Cfunc != 0 {
|
if ctxt.Cursym.Cfunc != 0 {
|
||||||
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
|
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
p.To.Sym = ctxt.Symmorestack[noctxt]
|
p.To.Sym = ctxt.Symmorestack[noctxt]
|
||||||
}
|
}
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJMP
|
p.As = obj.AJMP
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.Pcond = ctxt.Cursym.Text.Link
|
p.Pcond = ctxt.Cursym.Text.Link
|
||||||
|
|
||||||
if q != nil {
|
if q != nil {
|
||||||
@ -723,7 +687,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
|
|||||||
|
|
||||||
ctxt.Cursym = s
|
ctxt.Cursym = s
|
||||||
|
|
||||||
firstp = ctxt.NewProg()
|
firstp = new(obj.Prog)
|
||||||
lastp = firstp
|
lastp = firstp
|
||||||
xfol(ctxt, s.Text, &lastp)
|
xfol(ctxt, s.Text, &lastp)
|
||||||
lastp.Link = nil
|
lastp.Link = nil
|
||||||
@ -732,11 +696,11 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
|
|||||||
|
|
||||||
func nofollow(a int) int {
|
func nofollow(a int) int {
|
||||||
switch a {
|
switch a {
|
||||||
case AJMP,
|
case obj.AJMP,
|
||||||
ARET,
|
obj.ARET,
|
||||||
AIRETL,
|
AIRETL,
|
||||||
AIRETW,
|
AIRETW,
|
||||||
AUNDEF:
|
obj.AUNDEF:
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,9 +772,9 @@ loop:
|
|||||||
if p == nil {
|
if p == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if p.As == AJMP {
|
if p.As == obj.AJMP {
|
||||||
q = p.Pcond
|
q = p.Pcond
|
||||||
if q != nil && q.As != ATEXT {
|
if q != nil && q.As != obj.ATEXT {
|
||||||
/* mark instruction as done and continue layout at target of jump */
|
/* mark instruction as done and continue layout at target of jump */
|
||||||
p.Mark = 1
|
p.Mark = 1
|
||||||
|
|
||||||
@ -829,7 +793,6 @@ loop:
|
|||||||
i = 0
|
i = 0
|
||||||
q = p
|
q = p
|
||||||
for ; i < 4; (func() { i++; q = q.Link })() {
|
for ; i < 4; (func() { i++; q = q.Link })() {
|
||||||
|
|
||||||
if q == nil {
|
if q == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -837,7 +800,7 @@ loop:
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
a = int(q.As)
|
a = int(q.As)
|
||||||
if a == ANOP {
|
if a == obj.ANOP {
|
||||||
i--
|
i--
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -848,11 +811,11 @@ loop:
|
|||||||
if q.Pcond == nil || q.Pcond.Mark != 0 {
|
if q.Pcond == nil || q.Pcond.Mark != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if a == ACALL || a == ALOOP {
|
if a == obj.ACALL || a == ALOOP {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
if p.As == ANOP {
|
if p.As == obj.ANOP {
|
||||||
p = p.Link
|
p = p.Link
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -879,10 +842,10 @@ loop:
|
|||||||
/* */
|
/* */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
q.As = AJMP
|
q.As = obj.AJMP
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.To.Type = D_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q.To.Offset = p.Pc
|
q.To.Offset = p.Pc
|
||||||
q.Pcond = p
|
q.Pcond = p
|
||||||
p = q
|
p = q
|
||||||
@ -897,10 +860,9 @@ loop:
|
|||||||
|
|
||||||
/* continue loop with what comes after p */
|
/* continue loop with what comes after p */
|
||||||
if nofollow(a) != 0 {
|
if nofollow(a) != 0 {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if p.Pcond != nil && a != ACALL {
|
if p.Pcond != nil && a != obj.ACALL {
|
||||||
/*
|
/*
|
||||||
* some kind of conditional branch.
|
* some kind of conditional branch.
|
||||||
* recurse to follow one path.
|
* recurse to follow one path.
|
||||||
@ -908,14 +870,13 @@ loop:
|
|||||||
*/
|
*/
|
||||||
q = obj.Brchain(ctxt, p.Pcond)
|
q = obj.Brchain(ctxt, p.Pcond)
|
||||||
if q != nil {
|
if q != nil {
|
||||||
|
|
||||||
p.Pcond = q
|
p.Pcond = q
|
||||||
}
|
}
|
||||||
q = obj.Brchain(ctxt, p.Link)
|
q = obj.Brchain(ctxt, p.Link)
|
||||||
if q != nil {
|
if q != nil {
|
||||||
p.Link = q
|
p.Link = q
|
||||||
}
|
}
|
||||||
if p.From.Type == D_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
if p.From.Offset == 1 {
|
if p.From.Offset == 1 {
|
||||||
/*
|
/*
|
||||||
* expect conditional jump to be taken.
|
* expect conditional jump to be taken.
|
||||||
@ -928,7 +889,6 @@ loop:
|
|||||||
p.Pcond = q
|
p.Pcond = q
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
q = p.Link
|
q = p.Link
|
||||||
if q.Mark != 0 {
|
if q.Mark != 0 {
|
||||||
if a != ALOOP {
|
if a != ALOOP {
|
||||||
@ -952,45 +912,16 @@ loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
var Link386 = obj.LinkArch{
|
var Link386 = obj.LinkArch{
|
||||||
ByteOrder: binary.LittleEndian,
|
ByteOrder: binary.LittleEndian,
|
||||||
Pconv: Pconv,
|
Pconv: Pconv,
|
||||||
Name: "386",
|
Name: "386",
|
||||||
Thechar: '8',
|
Thechar: '8',
|
||||||
Endian: obj.LittleEndian,
|
Endian: obj.LittleEndian,
|
||||||
Addstacksplit: addstacksplit,
|
Preprocess: preprocess,
|
||||||
Assemble: span8,
|
Assemble: span8,
|
||||||
Datasize: datasize,
|
Follow: follow,
|
||||||
Follow: follow,
|
Progedit: progedit,
|
||||||
Iscall: iscall,
|
Minlc: 1,
|
||||||
Isdata: isdata,
|
Ptrsize: 4,
|
||||||
Prg: prg,
|
Regsize: 4,
|
||||||
Progedit: progedit,
|
|
||||||
Settextflag: settextflag,
|
|
||||||
Symtype: symtype,
|
|
||||||
Textflag: textflag,
|
|
||||||
Minlc: 1,
|
|
||||||
Ptrsize: 4,
|
|
||||||
Regsize: 4,
|
|
||||||
D_ADDR: D_ADDR,
|
|
||||||
D_AUTO: D_AUTO,
|
|
||||||
D_BRANCH: D_BRANCH,
|
|
||||||
D_CONST: D_CONST,
|
|
||||||
D_EXTERN: D_EXTERN,
|
|
||||||
D_FCONST: D_FCONST,
|
|
||||||
D_NONE: D_NONE,
|
|
||||||
D_PARAM: D_PARAM,
|
|
||||||
D_SCONST: D_SCONST,
|
|
||||||
D_STATIC: D_STATIC,
|
|
||||||
ACALL: ACALL,
|
|
||||||
ADATA: ADATA,
|
|
||||||
AEND: AEND,
|
|
||||||
AFUNCDATA: AFUNCDATA,
|
|
||||||
AGLOBL: AGLOBL,
|
|
||||||
AJMP: AJMP,
|
|
||||||
ANOP: ANOP,
|
|
||||||
APCDATA: APCDATA,
|
|
||||||
ARET: ARET,
|
|
||||||
ATEXT: ATEXT,
|
|
||||||
ATYPE: ATYPE,
|
|
||||||
AUSEFIELD: AUSEFIELD,
|
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,6 @@ func mkfwd(sym *LSym) {
|
|||||||
if i == 0 {
|
if i == 0 {
|
||||||
cnt[i] = 1
|
cnt[i] = 1
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
cnt[i] = LOG * cnt[i-1]
|
cnt[i] = LOG * cnt[i-1]
|
||||||
}
|
}
|
||||||
dwn[i] = 1
|
dwn[i] = 1
|
||||||
|
@ -33,24 +33,25 @@ package obj
|
|||||||
import "encoding/binary"
|
import "encoding/binary"
|
||||||
|
|
||||||
type Addr struct {
|
type Addr struct {
|
||||||
|
Type int16
|
||||||
|
Reg int16
|
||||||
|
Index int16
|
||||||
|
Scale int8
|
||||||
|
Name int8
|
||||||
Offset int64
|
Offset int64
|
||||||
|
Sym *LSym
|
||||||
U struct {
|
U struct {
|
||||||
Sval string
|
Sval string
|
||||||
Dval float64
|
Dval float64
|
||||||
Branch *Prog
|
Branch *Prog
|
||||||
|
Argsize int32
|
||||||
|
Bits uint64
|
||||||
}
|
}
|
||||||
Sym *LSym
|
Gotype *LSym
|
||||||
Gotype *LSym
|
Class int8
|
||||||
Type int16
|
Etype uint8
|
||||||
Index uint8
|
Node interface{}
|
||||||
Scale int8
|
Width int64
|
||||||
Reg int8
|
|
||||||
Name int8
|
|
||||||
Class int8
|
|
||||||
Etype uint8
|
|
||||||
Offset2 int32
|
|
||||||
Node interface{}
|
|
||||||
Width int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Prog struct {
|
type Prog struct {
|
||||||
@ -61,7 +62,7 @@ type Prog struct {
|
|||||||
As int16
|
As int16
|
||||||
Scond uint8
|
Scond uint8
|
||||||
From Addr
|
From Addr
|
||||||
Reg uint8
|
Reg int16
|
||||||
From3 Addr
|
From3 Addr
|
||||||
To Addr
|
To Addr
|
||||||
Opt interface{}
|
Opt interface{}
|
||||||
@ -79,7 +80,6 @@ type Prog struct {
|
|||||||
Printed uint8
|
Printed uint8
|
||||||
Width int8
|
Width int8
|
||||||
Mode int8
|
Mode int8
|
||||||
TEXTFLAG uint8
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LSym struct {
|
type LSym struct {
|
||||||
@ -149,7 +149,7 @@ type Auto struct {
|
|||||||
Asym *LSym
|
Asym *LSym
|
||||||
Link *Auto
|
Link *Auto
|
||||||
Aoffset int32
|
Aoffset int32
|
||||||
Type int16
|
Name int16
|
||||||
Gotype *LSym
|
Gotype *LSym
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,48 +240,18 @@ type Plist struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LinkArch struct {
|
type LinkArch struct {
|
||||||
Pconv func(*Prog) string
|
Pconv func(*Prog) string
|
||||||
Name string
|
ByteOrder binary.ByteOrder
|
||||||
Thechar int
|
Name string
|
||||||
Endian int32
|
Thechar int
|
||||||
ByteOrder binary.ByteOrder
|
Endian int32
|
||||||
Addstacksplit func(*Link, *LSym)
|
Preprocess func(*Link, *LSym)
|
||||||
Assemble func(*Link, *LSym)
|
Assemble func(*Link, *LSym)
|
||||||
Datasize func(*Prog) int
|
Follow func(*Link, *LSym)
|
||||||
Follow func(*Link, *LSym)
|
Progedit func(*Link, *Prog)
|
||||||
Iscall func(*Prog) bool
|
Minlc int
|
||||||
Isdata func(*Prog) bool
|
Ptrsize int
|
||||||
Prg func() *Prog
|
Regsize int
|
||||||
Progedit func(*Link, *Prog)
|
|
||||||
Settextflag func(*Prog, int)
|
|
||||||
Symtype func(*Addr) int
|
|
||||||
Textflag func(*Prog) int
|
|
||||||
Minlc int
|
|
||||||
Ptrsize int
|
|
||||||
Regsize int
|
|
||||||
D_ADDR int
|
|
||||||
D_AUTO int
|
|
||||||
D_BRANCH int
|
|
||||||
D_CONST int
|
|
||||||
D_EXTERN int
|
|
||||||
D_FCONST int
|
|
||||||
D_NONE int
|
|
||||||
D_PARAM int
|
|
||||||
D_SCONST int
|
|
||||||
D_STATIC int
|
|
||||||
D_OREG int
|
|
||||||
ACALL int
|
|
||||||
ADATA int
|
|
||||||
AEND int
|
|
||||||
AFUNCDATA int
|
|
||||||
AGLOBL int
|
|
||||||
AJMP int
|
|
||||||
ANOP int
|
|
||||||
APCDATA int
|
|
||||||
ARET int
|
|
||||||
ATEXT int
|
|
||||||
ATYPE int
|
|
||||||
AUSEFIELD int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Library struct {
|
type Library struct {
|
||||||
@ -318,7 +288,156 @@ type Pciter struct {
|
|||||||
done int
|
done int
|
||||||
}
|
}
|
||||||
|
|
||||||
// prevent incompatible type signatures between liblink and 8l on Plan 9
|
// An Addr is an argument to an instruction.
|
||||||
|
// The general forms and their encodings are:
|
||||||
|
//
|
||||||
|
// sym±offset(symkind)(reg)(index*scale)
|
||||||
|
// Memory reference at address &sym(symkind) + offset + reg + index*scale.
|
||||||
|
// Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted.
|
||||||
|
// If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg).
|
||||||
|
// To force a parsing as index*scale, write (index*1).
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_MEM
|
||||||
|
// name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE)
|
||||||
|
// sym = sym
|
||||||
|
// offset = ±offset
|
||||||
|
// reg = reg (REG_*)
|
||||||
|
// index = index (REG_*)
|
||||||
|
// scale = scale (1, 2, 4, 8)
|
||||||
|
//
|
||||||
|
// $<mem>
|
||||||
|
// Effective address of memory reference <mem>, defined above.
|
||||||
|
// Encoding: same as memory reference, but type = TYPE_ADDR.
|
||||||
|
//
|
||||||
|
// $<±integer value>
|
||||||
|
// This is a special case of $<mem>, in which only ±offset is present.
|
||||||
|
// It has a separate type for easy recognition.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_CONST
|
||||||
|
// offset = ±integer value
|
||||||
|
//
|
||||||
|
// *<mem>
|
||||||
|
// Indirect reference through memory reference <mem>, defined above.
|
||||||
|
// Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function
|
||||||
|
// pointer stored in the data word sym(SB), not a function named sym(SB).
|
||||||
|
// Encoding: same as above, but type = TYPE_INDIR.
|
||||||
|
//
|
||||||
|
// $*$<mem>
|
||||||
|
// No longer used.
|
||||||
|
// On machines with actual SB registers, $*$<mem> forced the
|
||||||
|
// instruction encoding to use a full 32-bit constant, never a
|
||||||
|
// reference relative to SB.
|
||||||
|
//
|
||||||
|
// $<floating point literal>
|
||||||
|
// Floating point constant value.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_FCONST
|
||||||
|
// u.dval = floating point value
|
||||||
|
//
|
||||||
|
// $<string literal, up to 8 chars>
|
||||||
|
// String literal value (raw bytes used for DATA instruction).
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_SCONST
|
||||||
|
// u.sval = string
|
||||||
|
//
|
||||||
|
// <register name>
|
||||||
|
// Any register: integer, floating point, control, segment, and so on.
|
||||||
|
// If looking for specific register kind, must check type and reg value range.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_REG
|
||||||
|
// reg = reg (REG_*)
|
||||||
|
//
|
||||||
|
// x(PC)
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_BRANCH
|
||||||
|
// u.branch = Prog* reference OR ELSE offset = target pc (branch takes priority)
|
||||||
|
//
|
||||||
|
// $±x-±y
|
||||||
|
// Final argument to TEXT, specifying local frame size x and argument size y.
|
||||||
|
// In this form, x and y are integer literals only, not arbitrary expressions.
|
||||||
|
// This avoids parsing ambiguities due to the use of - as a separator.
|
||||||
|
// The ± are optional.
|
||||||
|
// If the final argument to TEXT omits the -±y, the encoding should still
|
||||||
|
// use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_TEXTSIZE
|
||||||
|
// offset = x
|
||||||
|
// u.argsize = y
|
||||||
|
//
|
||||||
|
// reg<<shift, reg>>shift, reg->shift, reg@>shift
|
||||||
|
// Shifted register value, for ARM.
|
||||||
|
// In this form, reg must be a register and shift can be a register or an integer constant.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_SHIFT
|
||||||
|
// offset = (reg&15) | shifttype<<5 | count
|
||||||
|
// shifttype = 0, 1, 2, 3 for <<, >>, ->, @>
|
||||||
|
// count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant.
|
||||||
|
//
|
||||||
|
// (reg, reg)
|
||||||
|
// A destination register pair. When used as the last argument of an instruction,
|
||||||
|
// this form makes clear that both registers are destinations.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_REGREG
|
||||||
|
// reg = first register
|
||||||
|
// offset = second register
|
||||||
|
//
|
||||||
|
// reg, reg
|
||||||
|
// TYPE_REGREG2, to be removed.
|
||||||
|
//
|
||||||
|
|
||||||
|
const (
|
||||||
|
NAME_NONE = 0 + iota
|
||||||
|
NAME_EXTERN
|
||||||
|
NAME_STATIC
|
||||||
|
NAME_AUTO
|
||||||
|
NAME_PARAM
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TYPE_NONE = 0
|
||||||
|
TYPE_BRANCH = 5 + iota - 1
|
||||||
|
TYPE_TEXTSIZE
|
||||||
|
TYPE_MEM
|
||||||
|
TYPE_CONST
|
||||||
|
TYPE_FCONST
|
||||||
|
TYPE_SCONST
|
||||||
|
TYPE_REG
|
||||||
|
TYPE_ADDR
|
||||||
|
TYPE_SHIFT
|
||||||
|
TYPE_REGREG
|
||||||
|
TYPE_REGREG2
|
||||||
|
TYPE_INDIR
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO(rsc): Describe prog.
|
||||||
|
// TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3.
|
||||||
|
|
||||||
|
// Prog.as opcodes.
|
||||||
|
// These are the portable opcodes, common to all architectures.
|
||||||
|
// Each architecture defines many more arch-specific opcodes,
|
||||||
|
// with values starting at A_ARCHSPECIFIC.
|
||||||
|
const (
|
||||||
|
AXXX = 0 + iota
|
||||||
|
ACALL
|
||||||
|
ACHECKNIL
|
||||||
|
ADATA
|
||||||
|
ADUFFCOPY
|
||||||
|
ADUFFZERO
|
||||||
|
AEND
|
||||||
|
AFUNCDATA
|
||||||
|
AGLOBL
|
||||||
|
AJMP
|
||||||
|
ANOP
|
||||||
|
APCDATA
|
||||||
|
ARET
|
||||||
|
ATEXT
|
||||||
|
ATYPE
|
||||||
|
AUNDEF
|
||||||
|
AUSEFIELD
|
||||||
|
AVARDEF
|
||||||
|
AVARKILL
|
||||||
|
A_ARCHSPECIFIC
|
||||||
|
)
|
||||||
|
|
||||||
// prevent incompatible type signatures between liblink and 8l on Plan 9
|
// prevent incompatible type signatures between liblink and 8l on Plan 9
|
||||||
|
|
||||||
@ -397,7 +516,7 @@ const (
|
|||||||
RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1
|
RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
// Auto.type
|
// Auto.name
|
||||||
const (
|
const (
|
||||||
A_AUTO = 1 + iota
|
A_AUTO = 1 + iota
|
||||||
A_PARAM
|
A_PARAM
|
||||||
@ -461,3 +580,17 @@ const (
|
|||||||
// go.c
|
// go.c
|
||||||
|
|
||||||
// ld.c
|
// ld.c
|
||||||
|
|
||||||
|
// list[5689].c
|
||||||
|
|
||||||
|
// obj.c
|
||||||
|
|
||||||
|
// objfile.c
|
||||||
|
|
||||||
|
// pass.c
|
||||||
|
|
||||||
|
// pcln.c
|
||||||
|
|
||||||
|
// sym.c
|
||||||
|
|
||||||
|
var linkbasepointer int
|
||||||
|
@ -15,7 +15,7 @@ const (
|
|||||||
NSYM = 50
|
NSYM = 50
|
||||||
)
|
)
|
||||||
|
|
||||||
func linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string {
|
func Linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string {
|
||||||
var a [HISTSZ]struct {
|
var a [HISTSZ]struct {
|
||||||
incl *Hist
|
incl *Hist
|
||||||
idel int32
|
idel int32
|
||||||
@ -222,11 +222,9 @@ func Linklinehist(ctxt *Link, lineno int, f string, offset int) {
|
|||||||
if offset != 0 {
|
if offset != 0 {
|
||||||
fmt.Printf("%4d: %s (#line %d)\n", lineno, f, offset)
|
fmt.Printf("%4d: %s (#line %d)\n", lineno, f, offset)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
fmt.Printf("%4d: %s\n", lineno, f)
|
fmt.Printf("%4d: %s\n", lineno, f)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
fmt.Printf("%4d: <pop>\n", lineno)
|
fmt.Printf("%4d: <pop>\n", lineno)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,7 +295,6 @@ func Linkprfile(ctxt *Link, line int) {
|
|||||||
* start a new Prog list.
|
* start a new Prog list.
|
||||||
*/
|
*/
|
||||||
func Linknewplist(ctxt *Link) *Plist {
|
func Linknewplist(ctxt *Link) *Plist {
|
||||||
|
|
||||||
var pl *Plist
|
var pl *Plist
|
||||||
|
|
||||||
pl = new(Plist)
|
pl = new(Plist)
|
||||||
@ -305,7 +302,6 @@ func Linknewplist(ctxt *Link) *Plist {
|
|||||||
if ctxt.Plist == nil {
|
if ctxt.Plist == nil {
|
||||||
ctxt.Plist = pl
|
ctxt.Plist = pl
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ctxt.Plast.Link = pl
|
ctxt.Plast.Link = pl
|
||||||
}
|
}
|
||||||
ctxt.Plast = pl
|
ctxt.Plast = pl
|
||||||
|
@ -17,7 +17,6 @@ var outfile string
|
|||||||
// out a Go object file. The linker does not call this; the linker
|
// out a Go object file. The linker does not call this; the linker
|
||||||
// does not write out object files.
|
// does not write out object files.
|
||||||
func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
||||||
|
|
||||||
var flag int
|
var flag int
|
||||||
var found int
|
var found int
|
||||||
var h *Hist
|
var h *Hist
|
||||||
@ -44,16 +43,16 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
for pl = ctxt.Plist; pl != nil; pl = pl.Link {
|
for pl = ctxt.Plist; pl != nil; pl = pl.Link {
|
||||||
for p = pl.Firstpc; p != nil; p = plink {
|
for p = pl.Firstpc; p != nil; p = plink {
|
||||||
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
|
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
|
||||||
fmt.Printf("obj: %p %v\n", p, p)
|
fmt.Printf("obj: %v\n", p)
|
||||||
}
|
}
|
||||||
plink = p.Link
|
plink = p.Link
|
||||||
p.Link = nil
|
p.Link = nil
|
||||||
|
|
||||||
if int(p.As) == ctxt.Arch.AEND {
|
if p.As == AEND {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(p.As) == ctxt.Arch.ATYPE {
|
if p.As == ATYPE {
|
||||||
// Assume each TYPE instruction describes
|
// Assume each TYPE instruction describes
|
||||||
// a different local variable or parameter,
|
// a different local variable or parameter,
|
||||||
// so no dedup.
|
// so no dedup.
|
||||||
@ -66,20 +65,19 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
// If something else could use them, we could arrange to
|
// If something else could use them, we could arrange to
|
||||||
// preserve them.
|
// preserve them.
|
||||||
if curtext == nil {
|
if curtext == nil {
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
a = new(Auto)
|
a = new(Auto)
|
||||||
a.Asym = p.From.Sym
|
a.Asym = p.From.Sym
|
||||||
a.Aoffset = int32(p.From.Offset)
|
a.Aoffset = int32(p.From.Offset)
|
||||||
a.Type = int16(ctxt.Arch.Symtype(&p.From))
|
a.Name = int16(p.From.Name)
|
||||||
a.Gotype = p.From.Gotype
|
a.Gotype = p.From.Gotype
|
||||||
a.Link = curtext.Autom
|
a.Link = curtext.Autom
|
||||||
curtext.Autom = a
|
curtext.Autom = a
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(p.As) == ctxt.Arch.AGLOBL {
|
if p.As == AGLOBL {
|
||||||
s = p.From.Sym
|
s = p.From.Sym
|
||||||
tmp6 := s.Seenglobl
|
tmp6 := s.Seenglobl
|
||||||
s.Seenglobl++
|
s.Seenglobl++
|
||||||
@ -93,7 +91,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
data = s
|
data = s
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
edata.Next = s
|
edata.Next = s
|
||||||
}
|
}
|
||||||
s.Next = nil
|
s.Next = nil
|
||||||
@ -101,7 +98,7 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
if s.Type == 0 || s.Type == SXREF {
|
if s.Type == 0 || s.Type == SXREF {
|
||||||
s.Type = SBSS
|
s.Type = SBSS
|
||||||
}
|
}
|
||||||
flag = ctxt.Arch.Textflag(p)
|
flag = int(p.From3.Offset)
|
||||||
if flag&DUPOK != 0 {
|
if flag&DUPOK != 0 {
|
||||||
s.Dupok = 1
|
s.Dupok = 1
|
||||||
}
|
}
|
||||||
@ -114,12 +111,12 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(p.As) == ctxt.Arch.ADATA {
|
if p.As == ADATA {
|
||||||
savedata(ctxt, p.From.Sym, p, "<input>")
|
savedata(ctxt, p.From.Sym, p, "<input>")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(p.As) == ctxt.Arch.ATEXT {
|
if p.As == ATEXT {
|
||||||
s = p.From.Sym
|
s = p.From.Sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
// func _() { }
|
// func _() { }
|
||||||
@ -138,11 +135,10 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
if text == nil {
|
if text == nil {
|
||||||
text = s
|
text = s
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
etext.Next = s
|
etext.Next = s
|
||||||
}
|
}
|
||||||
etext = s
|
etext = s
|
||||||
flag = ctxt.Arch.Textflag(p)
|
flag = int(p.From3.Offset)
|
||||||
if flag&DUPOK != 0 {
|
if flag&DUPOK != 0 {
|
||||||
s.Dupok = 1
|
s.Dupok = 1
|
||||||
}
|
}
|
||||||
@ -157,16 +153,16 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(p.As) == ctxt.Arch.AFUNCDATA {
|
if p.As == AFUNCDATA {
|
||||||
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
|
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
|
||||||
if curtext == nil { // func _() {}
|
if curtext == nil { // func _() {}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if p.To.Sym.Name == "go_args_stackmap" {
|
if p.To.Sym.Name == "go_args_stackmap" {
|
||||||
if int(p.From.Type) != ctxt.Arch.D_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
|
if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
|
||||||
ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
|
ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
|
||||||
}
|
}
|
||||||
p.To.Sym = Linklookup(ctxt, string(fmt.Sprintf("%s.args_stackmap", curtext.Name)), int(curtext.Version))
|
p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,13 +177,12 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
|
|
||||||
// Add reference to Go arguments for C or assembly functions without them.
|
// Add reference to Go arguments for C or assembly functions without them.
|
||||||
for s = text; s != nil; s = s.Next {
|
for s = text; s != nil; s = s.Next {
|
||||||
|
|
||||||
if !strings.HasPrefix(s.Name, "\"\".") {
|
if !strings.HasPrefix(s.Name, "\"\".") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
found = 0
|
found = 0
|
||||||
for p = s.Text; p != nil; p = p.Link {
|
for p = s.Text; p != nil; p = p.Link {
|
||||||
if int(p.As) == ctxt.Arch.AFUNCDATA && int(p.From.Type) == ctxt.Arch.D_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps {
|
if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps {
|
||||||
found = 1
|
found = 1
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -195,28 +190,21 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
|
|
||||||
if !(found != 0) {
|
if !(found != 0) {
|
||||||
p = Appendp(ctxt, s.Text)
|
p = Appendp(ctxt, s.Text)
|
||||||
p.As = int16(ctxt.Arch.AFUNCDATA)
|
p.As = AFUNCDATA
|
||||||
p.From.Type = int16(ctxt.Arch.D_CONST)
|
p.From.Type = TYPE_CONST
|
||||||
p.From.Offset = FUNCDATA_ArgsPointerMaps
|
p.From.Offset = FUNCDATA_ArgsPointerMaps
|
||||||
if ctxt.Arch.Thechar == '6' || ctxt.Arch.Thechar == '8' {
|
p.To.Type = TYPE_MEM
|
||||||
p.To.Type = int16(ctxt.Arch.D_EXTERN)
|
p.To.Name = NAME_EXTERN
|
||||||
} else {
|
p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version))
|
||||||
|
|
||||||
p.To.Type = int16(ctxt.Arch.D_OREG)
|
|
||||||
p.To.Name = int8(ctxt.Arch.D_EXTERN)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.To.Sym = Linklookup(ctxt, string(fmt.Sprintf("%s.args_stackmap", s.Name)), int(s.Version))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn functions into machine code images.
|
// Turn functions into machine code images.
|
||||||
for s = text; s != nil; s = s.Next {
|
for s = text; s != nil; s = s.Next {
|
||||||
|
|
||||||
mkfwd(s)
|
mkfwd(s)
|
||||||
linkpatch(ctxt, s)
|
linkpatch(ctxt, s)
|
||||||
ctxt.Arch.Follow(ctxt, s)
|
ctxt.Arch.Follow(ctxt, s)
|
||||||
ctxt.Arch.Addstacksplit(ctxt, s)
|
ctxt.Arch.Preprocess(ctxt, s)
|
||||||
ctxt.Arch.Assemble(ctxt, s)
|
ctxt.Arch.Assemble(ctxt, s)
|
||||||
linkpcln(ctxt, s)
|
linkpcln(ctxt, s)
|
||||||
}
|
}
|
||||||
@ -230,7 +218,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
|
|
||||||
// Emit autolib.
|
// Emit autolib.
|
||||||
for h = ctxt.Hist; h != nil; h = h.Link {
|
for h = ctxt.Hist; h != nil; h = h.Link {
|
||||||
|
|
||||||
if h.Offset < 0 {
|
if h.Offset < 0 {
|
||||||
wrstring(b, h.Name)
|
wrstring(b, h.Name)
|
||||||
}
|
}
|
||||||
@ -239,7 +226,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
|
|||||||
|
|
||||||
// Emit symbols.
|
// Emit symbols.
|
||||||
for s = text; s != nil; s = s.Next {
|
for s = text; s != nil; s = s.Next {
|
||||||
|
|
||||||
writesym(ctxt, b, s)
|
writesym(ctxt, b, s)
|
||||||
}
|
}
|
||||||
for s = data; s != nil; s = s.Next {
|
for s = data; s != nil; s = s.Next {
|
||||||
@ -307,7 +293,6 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) {
|
|||||||
if ' ' <= c && c <= 0x7e {
|
if ' ' <= c && c <= 0x7e {
|
||||||
fmt.Fprintf(ctxt.Bso, "%c", c)
|
fmt.Fprintf(ctxt.Bso, "%c", c)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
fmt.Fprintf(ctxt.Bso, ".")
|
fmt.Fprintf(ctxt.Bso, ".")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,7 +310,6 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) {
|
|||||||
if ctxt.Arch.Thechar == '5' || ctxt.Arch.Thechar == '9' {
|
if ctxt.Arch.Thechar == '5' || ctxt.Arch.Thechar == '9' {
|
||||||
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(int64(r.Add)))
|
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(int64(r.Add)))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, int64(r.Add))
|
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, int64(r.Add))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,13 +349,12 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) {
|
|||||||
for a = s.Autom; a != nil; a = a.Link {
|
for a = s.Autom; a != nil; a = a.Link {
|
||||||
wrsym(b, a.Asym)
|
wrsym(b, a.Asym)
|
||||||
wrint(b, int64(a.Aoffset))
|
wrint(b, int64(a.Aoffset))
|
||||||
if int(a.Type) == ctxt.Arch.D_AUTO {
|
if a.Name == NAME_AUTO {
|
||||||
wrint(b, A_AUTO)
|
wrint(b, A_AUTO)
|
||||||
} else if int(a.Type) == ctxt.Arch.D_PARAM {
|
} else if a.Name == NAME_PARAM {
|
||||||
wrint(b, A_PARAM)
|
wrint(b, A_PARAM)
|
||||||
} else {
|
} else {
|
||||||
|
log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name)
|
||||||
log.Fatalf("%s: invalid local variable type %d", s.Name, a.Type)
|
|
||||||
}
|
}
|
||||||
wrsym(b, a.Gotype)
|
wrsym(b, a.Gotype)
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,10 @@ package obj
|
|||||||
// Code and data passes.
|
// Code and data passes.
|
||||||
|
|
||||||
func Brchain(ctxt *Link, p *Prog) *Prog {
|
func Brchain(ctxt *Link, p *Prog) *Prog {
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
|
|
||||||
for i = 0; i < 20; i++ {
|
for i = 0; i < 20; i++ {
|
||||||
if p == nil || int(p.As) != ctxt.Arch.AJMP || p.Pcond == nil {
|
if p == nil || p.As != AJMP || p.Pcond == nil {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
p = p.Pcond
|
p = p.Pcond
|
||||||
@ -52,7 +51,7 @@ func brloop(ctxt *Link, p *Prog) *Prog {
|
|||||||
|
|
||||||
c = 0
|
c = 0
|
||||||
for q = p; q != nil; q = q.Pcond {
|
for q = p; q != nil; q = q.Pcond {
|
||||||
if int(q.As) != ctxt.Arch.AJMP || q.Pcond == nil {
|
if q.As != AJMP || q.Pcond == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c++
|
c++
|
||||||
@ -64,6 +63,92 @@ func brloop(ctxt *Link, p *Prog) *Prog {
|
|||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkaddr(ctxt *Link, p *Prog, a *Addr) {
|
||||||
|
// Check expected encoding, especially TYPE_CONST vs TYPE_ADDR.
|
||||||
|
switch a.Type {
|
||||||
|
case TYPE_NONE:
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_BRANCH:
|
||||||
|
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_TEXTSIZE:
|
||||||
|
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
//if(a->u.bits != 0)
|
||||||
|
// break;
|
||||||
|
case TYPE_MEM:
|
||||||
|
return
|
||||||
|
|
||||||
|
// TODO(rsc): After fixing SHRQ, check a->index != 0 too.
|
||||||
|
case TYPE_CONST:
|
||||||
|
if a.Name != 0 || a.Sym != nil || a.Reg != 0 {
|
||||||
|
ctxt.Diag("argument is TYPE_CONST, should be TYPE_ADDR, in %v", p)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.Reg != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_FCONST,
|
||||||
|
TYPE_SCONST:
|
||||||
|
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Offset != 0 || a.Sym != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_ADDR:
|
||||||
|
if a.U.Bits != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if a.Reg == 0 && a.Index == 0 && a.Scale == 0 && a.Name == 0 && a.Sym == nil {
|
||||||
|
ctxt.Diag("argument is TYPE_ADDR, should be TYPE_CONST, in %v", p)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_SHIFT:
|
||||||
|
if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_REGREG:
|
||||||
|
if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_REGREG2:
|
||||||
|
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 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt.Diag("invalid encoding for argument %v", p)
|
||||||
|
}
|
||||||
|
|
||||||
func linkpatch(ctxt *Link, sym *LSym) {
|
func linkpatch(ctxt *Link, sym *LSym) {
|
||||||
var c int32
|
var c int32
|
||||||
var name string
|
var name string
|
||||||
@ -73,10 +158,14 @@ func linkpatch(ctxt *Link, sym *LSym) {
|
|||||||
ctxt.Cursym = sym
|
ctxt.Cursym = sym
|
||||||
|
|
||||||
for p = sym.Text; p != nil; p = p.Link {
|
for p = sym.Text; p != nil; p = p.Link {
|
||||||
|
checkaddr(ctxt, p, &p.From)
|
||||||
|
checkaddr(ctxt, p, &p.From3)
|
||||||
|
checkaddr(ctxt, p, &p.To)
|
||||||
|
|
||||||
if ctxt.Arch.Progedit != nil {
|
if ctxt.Arch.Progedit != nil {
|
||||||
ctxt.Arch.Progedit(ctxt, p)
|
ctxt.Arch.Progedit(ctxt, p)
|
||||||
}
|
}
|
||||||
if int(p.To.Type) != ctxt.Arch.D_BRANCH {
|
if p.To.Type != TYPE_BRANCH {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if p.To.U.Branch != nil {
|
if p.To.U.Branch != nil {
|
||||||
@ -97,7 +186,6 @@ func linkpatch(ctxt *Link, sym *LSym) {
|
|||||||
if q.Forwd != nil && int64(c) >= q.Forwd.Pc {
|
if q.Forwd != nil && int64(c) >= q.Forwd.Pc {
|
||||||
q = q.Forwd
|
q = q.Forwd
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
q = q.Link
|
q = q.Link
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +196,7 @@ func linkpatch(ctxt *Link, sym *LSym) {
|
|||||||
name = p.To.Sym.Name
|
name = p.To.Sym.Name
|
||||||
}
|
}
|
||||||
ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name)
|
ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name)
|
||||||
p.To.Type = int16(ctxt.Arch.D_NONE)
|
p.To.Type = TYPE_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
p.To.U.Branch = q
|
p.To.U.Branch = q
|
||||||
@ -120,7 +208,7 @@ func linkpatch(ctxt *Link, sym *LSym) {
|
|||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
p.Pcond = brloop(ctxt, p.Pcond)
|
p.Pcond = brloop(ctxt, p.Pcond)
|
||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
if int(p.To.Type) == ctxt.Arch.D_BRANCH {
|
if p.To.Type == TYPE_BRANCH {
|
||||||
p.To.Offset = p.Pcond.Pc
|
p.To.Offset = p.Pcond.Pc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ func addvarint(ctxt *Link, d *Pcdata, val uint32) {
|
|||||||
// where func is the function, val is the current value, p is the instruction being
|
// where func is the function, val is the current value, p is the instruction being
|
||||||
// considered, and arg can be used to further parameterize valfunc.
|
// considered, and arg can be used to further parameterize valfunc.
|
||||||
func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) {
|
func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) {
|
||||||
|
|
||||||
var dbg int
|
var dbg int
|
||||||
var i int
|
var i int
|
||||||
var oldval int32
|
var oldval int32
|
||||||
@ -83,7 +82,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
|
|||||||
// instruction. Keep going, so that we only emit a delta
|
// instruction. Keep going, so that we only emit a delta
|
||||||
// for a true instruction boundary in the program.
|
// for a true instruction boundary in the program.
|
||||||
if p.Link != nil && p.Link.Pc == p.Pc {
|
if p.Link != nil && p.Link.Pc == p.Pc {
|
||||||
|
|
||||||
val = valfunc(ctxt, func_, val, p, 1, arg)
|
val = valfunc(ctxt, func_, val, p, 1, arg)
|
||||||
if ctxt.Debugpcln != 0 {
|
if ctxt.Debugpcln != 0 {
|
||||||
fmt.Fprintf(ctxt.Bso, "%6x %6s %v\n", uint64(int64(p.Pc)), "", p)
|
fmt.Fprintf(ctxt.Bso, "%6x %6s %v\n", uint64(int64(p.Pc)), "", p)
|
||||||
@ -106,7 +104,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
|
|||||||
// where the 0x80 bit indicates that the integer continues.
|
// where the 0x80 bit indicates that the integer continues.
|
||||||
|
|
||||||
if ctxt.Debugpcln != 0 {
|
if ctxt.Debugpcln != 0 {
|
||||||
|
|
||||||
fmt.Fprintf(ctxt.Bso, "%6x %6d %v\n", uint64(int64(p.Pc)), val, p)
|
fmt.Fprintf(ctxt.Bso, "%6x %6d %v\n", uint64(int64(p.Pc)), val, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +116,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
|
|||||||
if delta>>31 != 0 {
|
if delta>>31 != 0 {
|
||||||
delta = 1 | ^(delta << 1)
|
delta = 1 | ^(delta << 1)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
delta <<= 1
|
delta <<= 1
|
||||||
}
|
}
|
||||||
addvarint(ctxt, dst, delta)
|
addvarint(ctxt, dst, delta)
|
||||||
@ -152,13 +148,12 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
|
|||||||
// Because p->lineno applies to p, phase == 0 (before p)
|
// Because p->lineno applies to p, phase == 0 (before p)
|
||||||
// takes care of the update.
|
// takes care of the update.
|
||||||
func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
||||||
|
|
||||||
var i int32
|
var i int32
|
||||||
var l int32
|
var l int32
|
||||||
var f *LSym
|
var f *LSym
|
||||||
var pcln *Pcln
|
var pcln *Pcln
|
||||||
|
|
||||||
if int(p.As) == ctxt.Arch.ATEXT || int(p.As) == ctxt.Arch.ANOP || int(p.As) == ctxt.Arch.AUSEFIELD || p.Lineno == 0 || phase == 1 {
|
if p.As == ATEXT || p.As == ANOP || p.As == AUSEFIELD || p.Lineno == 0 || phase == 1 {
|
||||||
return oldval
|
return oldval
|
||||||
}
|
}
|
||||||
linkgetline(ctxt, p.Lineno, &f, &l)
|
linkgetline(ctxt, p.Lineno, &f, &l)
|
||||||
@ -195,7 +190,6 @@ func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg
|
|||||||
// The adjustment by p takes effect only after p, so we
|
// The adjustment by p takes effect only after p, so we
|
||||||
// apply the change during phase == 1.
|
// apply the change during phase == 1.
|
||||||
func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
||||||
|
|
||||||
if oldval == -1 { // starting
|
if oldval == -1 { // starting
|
||||||
oldval = 0
|
oldval = 0
|
||||||
}
|
}
|
||||||
@ -216,8 +210,7 @@ func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg in
|
|||||||
// Since PCDATA instructions have no width in the final code,
|
// Since PCDATA instructions have no width in the final code,
|
||||||
// it does not matter which phase we use for the update.
|
// it does not matter which phase we use for the update.
|
||||||
func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
||||||
|
if phase == 0 || p.As != APCDATA || p.From.Offset != int64(arg.(uint32)) {
|
||||||
if phase == 0 || int(p.As) != ctxt.Arch.APCDATA || p.From.Offset != int64(arg.(uint32)) {
|
|
||||||
return oldval
|
return oldval
|
||||||
}
|
}
|
||||||
if int64(int32(p.To.Offset)) != p.To.Offset {
|
if int64(int32(p.To.Offset)) != p.To.Offset {
|
||||||
@ -243,10 +236,10 @@ func linkpcln(ctxt *Link, cursym *LSym) {
|
|||||||
npcdata = 0
|
npcdata = 0
|
||||||
nfuncdata = 0
|
nfuncdata = 0
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p = cursym.Text; p != nil; p = p.Link {
|
||||||
if int(p.As) == ctxt.Arch.APCDATA && p.From.Offset >= int64(npcdata) {
|
if p.As == APCDATA && p.From.Offset >= int64(npcdata) {
|
||||||
npcdata = int(p.From.Offset + 1)
|
npcdata = int(p.From.Offset + 1)
|
||||||
}
|
}
|
||||||
if int(p.As) == ctxt.Arch.AFUNCDATA && p.From.Offset >= int64(nfuncdata) {
|
if p.As == AFUNCDATA && p.From.Offset >= int64(nfuncdata) {
|
||||||
nfuncdata = int(p.From.Offset + 1)
|
nfuncdata = int(p.From.Offset + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,21 +258,20 @@ func linkpcln(ctxt *Link, cursym *LSym) {
|
|||||||
havepc := make([]uint32, (npcdata+31)/32)
|
havepc := make([]uint32, (npcdata+31)/32)
|
||||||
havefunc := make([]uint32, (nfuncdata+31)/32)
|
havefunc := make([]uint32, (nfuncdata+31)/32)
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p = cursym.Text; p != nil; p = p.Link {
|
||||||
if int(p.As) == ctxt.Arch.AFUNCDATA {
|
if p.As == AFUNCDATA {
|
||||||
if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 {
|
if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 {
|
||||||
ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset)
|
ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset)
|
||||||
}
|
}
|
||||||
havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
|
havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(p.As) == ctxt.Arch.APCDATA {
|
if p.As == APCDATA {
|
||||||
havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
|
havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pcdata.
|
// pcdata.
|
||||||
for i = 0; i < npcdata; i++ {
|
for i = 0; i < npcdata; i++ {
|
||||||
|
|
||||||
if (havepc[i/32]>>uint(i%32))&1 == 0 {
|
if (havepc[i/32]>>uint(i%32))&1 == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -288,12 +280,11 @@ func linkpcln(ctxt *Link, cursym *LSym) {
|
|||||||
|
|
||||||
// funcdata
|
// funcdata
|
||||||
if nfuncdata > 0 {
|
if nfuncdata > 0 {
|
||||||
|
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p = cursym.Text; p != nil; p = p.Link {
|
||||||
if int(p.As) == ctxt.Arch.AFUNCDATA {
|
if p.As == AFUNCDATA {
|
||||||
i = int(p.From.Offset)
|
i = int(p.From.Offset)
|
||||||
pcln.Funcdataoff[i] = p.To.Offset
|
pcln.Funcdataoff[i] = p.To.Offset
|
||||||
if int(p.To.Type) != ctxt.Arch.D_CONST {
|
if p.To.Type != TYPE_CONST {
|
||||||
// TODO: Dedup.
|
// TODO: Dedup.
|
||||||
//funcdata_bytes += p->to.sym->size;
|
//funcdata_bytes += p->to.sym->size;
|
||||||
pcln.Funcdata[i] = p.To.Sym
|
pcln.Funcdata[i] = p.To.Sym
|
||||||
@ -306,7 +297,6 @@ func linkpcln(ctxt *Link, cursym *LSym) {
|
|||||||
// iteration over encoded pcdata tables.
|
// iteration over encoded pcdata tables.
|
||||||
|
|
||||||
func getvarint(pp *[]byte) uint32 {
|
func getvarint(pp *[]byte) uint32 {
|
||||||
|
|
||||||
var p []byte
|
var p []byte
|
||||||
var shift int
|
var shift int
|
||||||
var v uint32
|
var v uint32
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
package ppc64
|
package ppc64
|
||||||
|
|
||||||
|
import "cmd/internal/obj"
|
||||||
|
|
||||||
// auto generated by go tool dist
|
// auto generated by go tool dist
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -41,30 +43,112 @@ const (
|
|||||||
NFREG = 32
|
NFREG = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// avoid conflict with ucontext.h. sigh.
|
||||||
const (
|
const (
|
||||||
REGZERO = 0
|
REG_R0 = 32 + iota
|
||||||
REGSP = 1
|
REG_R1
|
||||||
REGSB = 2
|
REG_R2
|
||||||
REGRET = 3
|
REG_R3
|
||||||
|
REG_R4
|
||||||
|
REG_R5
|
||||||
|
REG_R6
|
||||||
|
REG_R7
|
||||||
|
REG_R8
|
||||||
|
REG_R9
|
||||||
|
REG_R10
|
||||||
|
REG_R11
|
||||||
|
REG_R12
|
||||||
|
REG_R13
|
||||||
|
REG_R14
|
||||||
|
REG_R15
|
||||||
|
REG_R16
|
||||||
|
REG_R17
|
||||||
|
REG_R18
|
||||||
|
REG_R19
|
||||||
|
REG_R20
|
||||||
|
REG_R21
|
||||||
|
REG_R22
|
||||||
|
REG_R23
|
||||||
|
REG_R24
|
||||||
|
REG_R25
|
||||||
|
REG_R26
|
||||||
|
REG_R27
|
||||||
|
REG_R28
|
||||||
|
REG_R29
|
||||||
|
REG_R30
|
||||||
|
REG_R31
|
||||||
|
REG_F0 = 64 + iota - 32
|
||||||
|
REG_F1
|
||||||
|
REG_F2
|
||||||
|
REG_F3
|
||||||
|
REG_F4
|
||||||
|
REG_F5
|
||||||
|
REG_F6
|
||||||
|
REG_F7
|
||||||
|
REG_F8
|
||||||
|
REG_F9
|
||||||
|
REG_F10
|
||||||
|
REG_F11
|
||||||
|
REG_F12
|
||||||
|
REG_F13
|
||||||
|
REG_F14
|
||||||
|
REG_F15
|
||||||
|
REG_F16
|
||||||
|
REG_F17
|
||||||
|
REG_F18
|
||||||
|
REG_F19
|
||||||
|
REG_F20
|
||||||
|
REG_F21
|
||||||
|
REG_F22
|
||||||
|
REG_F23
|
||||||
|
REG_F24
|
||||||
|
REG_F25
|
||||||
|
REG_F26
|
||||||
|
REG_F27
|
||||||
|
REG_F28
|
||||||
|
REG_F29
|
||||||
|
REG_F30
|
||||||
|
REG_F31
|
||||||
|
REG_SPECIAL = 96
|
||||||
|
REG_C0 = 96 + iota - 65
|
||||||
|
REG_C1
|
||||||
|
REG_C2
|
||||||
|
REG_C3
|
||||||
|
REG_C4
|
||||||
|
REG_C5
|
||||||
|
REG_C6
|
||||||
|
REG_C7
|
||||||
|
REG_MSR = 104 + iota - 73
|
||||||
|
REG_FPSCR
|
||||||
|
REG_CR
|
||||||
|
REG_SPR0 = 1024
|
||||||
|
REG_DCR0 = 2048
|
||||||
|
REG_XER = REG_SPR0 + 1
|
||||||
|
REG_LR = REG_SPR0 + 8
|
||||||
|
REG_CTR = REG_SPR0 + 9
|
||||||
|
REGZERO = REG_R0
|
||||||
|
REGSP = REG_R1
|
||||||
|
REGSB = REG_R2
|
||||||
|
REGRET = REG_R3
|
||||||
REGARG = -1
|
REGARG = -1
|
||||||
REGRT1 = 3
|
REGRT1 = REG_R3
|
||||||
REGRT2 = 4
|
REGRT2 = REG_R4
|
||||||
REGMIN = 7
|
REGMIN = REG_R7
|
||||||
REGENV = 11
|
REGENV = REG_R11
|
||||||
REGTLS = 13
|
REGTLS = REG_R13
|
||||||
REGMAX = 27
|
REGMAX = REG_R27
|
||||||
REGEXT = 30
|
REGEXT = REG_R30
|
||||||
REGG = 30
|
REGG = REG_R30
|
||||||
REGTMP = 31
|
REGTMP = REG_R31
|
||||||
FREGRET = 0
|
FREGRET = REG_F0
|
||||||
FREGMIN = 17
|
FREGMIN = REG_F17
|
||||||
FREGMAX = 26
|
FREGMAX = REG_F26
|
||||||
FREGEXT = 26
|
FREGEXT = REG_F26
|
||||||
FREGCVI = 27
|
FREGCVI = REG_F27
|
||||||
FREGZERO = 28
|
FREGZERO = REG_F28
|
||||||
FREGHALF = 29
|
FREGHALF = REG_F29
|
||||||
FREGONE = 30
|
FREGONE = REG_F30
|
||||||
FREGTWO = 31
|
FREGTWO = REG_F31
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -129,12 +213,12 @@ const (
|
|||||||
C_ANY
|
C_ANY
|
||||||
C_GOK
|
C_GOK
|
||||||
C_ADDR
|
C_ADDR
|
||||||
|
C_TEXTSIZE
|
||||||
C_NCLASS
|
C_NCLASS
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AXXX = iota
|
AADD = obj.A_ARCHSPECIFIC + iota
|
||||||
AADD
|
|
||||||
AADDCC
|
AADDCC
|
||||||
AADDV
|
AADDV
|
||||||
AADDVCC
|
AADDVCC
|
||||||
@ -163,11 +247,9 @@ const (
|
|||||||
ABEQ
|
ABEQ
|
||||||
ABGE
|
ABGE
|
||||||
ABGT
|
ABGT
|
||||||
ABL
|
|
||||||
ABLE
|
ABLE
|
||||||
ABLT
|
ABLT
|
||||||
ABNE
|
ABNE
|
||||||
ABR
|
|
||||||
ABVC
|
ABVC
|
||||||
ABVS
|
ABVS
|
||||||
ACMP
|
ACMP
|
||||||
@ -349,19 +431,7 @@ const (
|
|||||||
ATLBSYNC
|
ATLBSYNC
|
||||||
ATW
|
ATW
|
||||||
ASYSCALL
|
ASYSCALL
|
||||||
ADATA
|
|
||||||
AGLOBL
|
|
||||||
AGOK
|
|
||||||
AHISTORY
|
|
||||||
ANAME
|
|
||||||
ANOP
|
|
||||||
ARETURN
|
|
||||||
ATEXT
|
|
||||||
AWORD
|
AWORD
|
||||||
AEND
|
|
||||||
ADYNT
|
|
||||||
AINIT
|
|
||||||
ASIGNAME
|
|
||||||
ARFCI
|
ARFCI
|
||||||
AFRES
|
AFRES
|
||||||
AFRESCC
|
AFRESCC
|
||||||
@ -438,48 +508,8 @@ const (
|
|||||||
AREMDUV
|
AREMDUV
|
||||||
AREMDUVCC
|
AREMDUVCC
|
||||||
AHRFID
|
AHRFID
|
||||||
AUNDEF
|
|
||||||
AUSEFIELD
|
|
||||||
ATYPE
|
|
||||||
AFUNCDATA
|
|
||||||
APCDATA
|
|
||||||
ACHECKNIL
|
|
||||||
AVARDEF
|
|
||||||
AVARKILL
|
|
||||||
ADUFFCOPY
|
|
||||||
ADUFFZERO
|
|
||||||
ALAST
|
ALAST
|
||||||
)
|
ABR = obj.AJMP
|
||||||
|
ABL = obj.ACALL
|
||||||
/* type/name */
|
ARETURN = obj.ARET
|
||||||
const (
|
|
||||||
D_GOK = 0 + iota
|
|
||||||
D_NONE
|
|
||||||
D_EXTERN
|
|
||||||
D_STATIC
|
|
||||||
D_AUTO
|
|
||||||
D_PARAM
|
|
||||||
D_BRANCH
|
|
||||||
D_OREG
|
|
||||||
D_CONST
|
|
||||||
D_FCONST
|
|
||||||
D_SCONST
|
|
||||||
D_REG
|
|
||||||
D_FPSCR
|
|
||||||
D_MSR
|
|
||||||
D_FREG
|
|
||||||
D_CREG
|
|
||||||
D_SPR
|
|
||||||
D_OPT
|
|
||||||
D_FILE
|
|
||||||
D_FILE1
|
|
||||||
D_DCR
|
|
||||||
D_DCONST
|
|
||||||
D_ADDR
|
|
||||||
D_LAST
|
|
||||||
D_R0 = 0
|
|
||||||
D_F0 = D_R0 + NREG
|
|
||||||
D_XER = 1
|
|
||||||
D_LR = 8
|
|
||||||
D_CTR = 9
|
|
||||||
)
|
)
|
||||||
|
@ -1,13 +1,29 @@
|
|||||||
package ppc64
|
package ppc64
|
||||||
|
|
||||||
/* and many supervisor level registers */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is the ranlib header
|
* this is the ranlib header
|
||||||
*/
|
*/
|
||||||
var Anames = []string{
|
var Anames = []string{
|
||||||
"XXX",
|
"XXX ",
|
||||||
"ADD",
|
"CALL",
|
||||||
|
"CHECKNIL",
|
||||||
|
"DATA",
|
||||||
|
"DUFFCOPY",
|
||||||
|
"DUFFZERO",
|
||||||
|
"END",
|
||||||
|
"FUNCDATA",
|
||||||
|
"GLOBL",
|
||||||
|
"JMP",
|
||||||
|
"NOP",
|
||||||
|
"PCDATA",
|
||||||
|
"RET",
|
||||||
|
"TEXT",
|
||||||
|
"TYPE",
|
||||||
|
"UNDEF",
|
||||||
|
"USEFIELD",
|
||||||
|
"VARDEF",
|
||||||
|
"VARKILL",
|
||||||
|
"ADD ",
|
||||||
"ADDCC",
|
"ADDCC",
|
||||||
"ADDV",
|
"ADDV",
|
||||||
"ADDVCC",
|
"ADDVCC",
|
||||||
@ -36,11 +52,9 @@ var Anames = []string{
|
|||||||
"BEQ",
|
"BEQ",
|
||||||
"BGE",
|
"BGE",
|
||||||
"BGT",
|
"BGT",
|
||||||
"BL",
|
|
||||||
"BLE",
|
"BLE",
|
||||||
"BLT",
|
"BLT",
|
||||||
"BNE",
|
"BNE",
|
||||||
"BR",
|
|
||||||
"BVC",
|
"BVC",
|
||||||
"BVS",
|
"BVS",
|
||||||
"CMP",
|
"CMP",
|
||||||
@ -222,19 +236,7 @@ var Anames = []string{
|
|||||||
"TLBSYNC",
|
"TLBSYNC",
|
||||||
"TW",
|
"TW",
|
||||||
"SYSCALL",
|
"SYSCALL",
|
||||||
"DATA",
|
|
||||||
"GLOBL",
|
|
||||||
"GOK",
|
|
||||||
"HISTORY",
|
|
||||||
"NAME",
|
|
||||||
"NOP",
|
|
||||||
"RETURN",
|
|
||||||
"TEXT",
|
|
||||||
"WORD",
|
"WORD",
|
||||||
"END",
|
|
||||||
"DYNT",
|
|
||||||
"INIT",
|
|
||||||
"SIGNAME",
|
|
||||||
"RFCI",
|
"RFCI",
|
||||||
"FRES",
|
"FRES",
|
||||||
"FRESCC",
|
"FRESCC",
|
||||||
@ -311,16 +313,6 @@ var Anames = []string{
|
|||||||
"REMDUV",
|
"REMDUV",
|
||||||
"REMDUVCC",
|
"REMDUVCC",
|
||||||
"HRFID",
|
"HRFID",
|
||||||
"UNDEF",
|
|
||||||
"USEFIELD",
|
|
||||||
"TYPE",
|
|
||||||
"FUNCDATA",
|
|
||||||
"PCDATA",
|
|
||||||
"CHECKNIL",
|
|
||||||
"VARDEF",
|
|
||||||
"VARKILL",
|
|
||||||
"DUFFCOPY",
|
|
||||||
"DUFFZERO",
|
|
||||||
"LAST",
|
"LAST",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,31 +351,6 @@ var cnames9 = []string{
|
|||||||
"ANY",
|
"ANY",
|
||||||
"GOK",
|
"GOK",
|
||||||
"ADDR",
|
"ADDR",
|
||||||
|
"TEXTSIZE",
|
||||||
"NCLASS",
|
"NCLASS",
|
||||||
}
|
}
|
||||||
|
|
||||||
var dnames9 = []string{
|
|
||||||
D_GOK: "GOK/R0",
|
|
||||||
D_NONE: "NONE/XER",
|
|
||||||
D_EXTERN: "EXTERN",
|
|
||||||
D_STATIC: "STATIC",
|
|
||||||
D_AUTO: "AUTO",
|
|
||||||
D_PARAM: "PARAM",
|
|
||||||
D_BRANCH: "BRANCH",
|
|
||||||
D_OREG: "OREG",
|
|
||||||
D_CONST: "CONST/LR",
|
|
||||||
D_FCONST: "FCONST/CTR",
|
|
||||||
D_SCONST: "SCONST",
|
|
||||||
D_REG: "REG",
|
|
||||||
D_FPSCR: "FPSCR",
|
|
||||||
D_MSR: "MSR",
|
|
||||||
D_FREG: "FREG",
|
|
||||||
D_CREG: "CREG",
|
|
||||||
D_SPR: "SPR",
|
|
||||||
D_OPT: "OPT",
|
|
||||||
D_FILE: "FILE",
|
|
||||||
D_FILE1: "FILE1",
|
|
||||||
D_DCR: "DCR",
|
|
||||||
D_DCONST: "DCONST",
|
|
||||||
D_ADDR: "ADDR",
|
|
||||||
}
|
|
||||||
|
@ -58,14 +58,10 @@ type Optab struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var optab = []Optab{
|
var optab = []Optab{
|
||||||
Optab{ATEXT, C_LEXT, C_NONE, C_NONE, C_LCON, 0, 0, 0},
|
Optab{obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
|
||||||
Optab{ATEXT, C_LEXT, C_REG, C_NONE, C_LCON, 0, 0, 0},
|
Optab{obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
|
||||||
Optab{ATEXT, C_LEXT, C_NONE, C_LCON, C_LCON, 0, 0, 0},
|
Optab{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
|
||||||
Optab{ATEXT, C_LEXT, C_REG, C_LCON, C_LCON, 0, 0, 0},
|
Optab{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
|
||||||
Optab{ATEXT, C_ADDR, C_NONE, C_NONE, C_LCON, 0, 0, 0},
|
|
||||||
Optab{ATEXT, C_ADDR, C_REG, C_NONE, C_LCON, 0, 0, 0},
|
|
||||||
Optab{ATEXT, C_ADDR, C_NONE, C_LCON, C_LCON, 0, 0, 0},
|
|
||||||
Optab{ATEXT, C_ADDR, C_REG, C_LCON, C_LCON, 0, 0, 0},
|
|
||||||
/* move register */
|
/* move register */
|
||||||
Optab{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
|
Optab{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
|
||||||
Optab{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
|
Optab{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
|
||||||
@ -389,15 +385,15 @@ var optab = []Optab{
|
|||||||
Optab{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
|
Optab{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
|
||||||
Optab{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
|
Optab{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
|
||||||
Optab{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
|
Optab{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
|
||||||
Optab{AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
|
Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
|
||||||
Optab{AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0},
|
Optab{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0},
|
||||||
Optab{APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
|
Optab{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
|
||||||
Optab{AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
|
Optab{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
|
||||||
Optab{ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
|
Optab{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
|
||||||
Optab{ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
|
Optab{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
|
||||||
Optab{ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
|
Optab{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
|
||||||
|
|
||||||
Optab{AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
|
Optab{obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
type Oprang struct {
|
type Oprang struct {
|
||||||
@ -426,7 +422,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctxt.Cursym = cursym
|
ctxt.Cursym = cursym
|
||||||
ctxt.Autosize = int32(p.To.Offset&0xffffffff) + 8
|
ctxt.Autosize = int32(p.To.Offset + 8)
|
||||||
|
|
||||||
if oprange[AANDN].start == nil {
|
if oprange[AANDN].start == nil {
|
||||||
buildop(ctxt)
|
buildop(ctxt)
|
||||||
@ -441,7 +437,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
o = oplook(ctxt, p)
|
o = oplook(ctxt, p)
|
||||||
m = int(o.size)
|
m = int(o.size)
|
||||||
if m == 0 {
|
if m == 0 {
|
||||||
if p.As != ANOP && p.As != AFUNCDATA && p.As != APCDATA {
|
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
|
||||||
ctxt.Diag("zero-width instruction\n%v", p)
|
ctxt.Diag("zero-width instruction\n%v", p)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -472,21 +468,20 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
// very large conditional branches
|
// very large conditional branches
|
||||||
if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
|
if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
|
||||||
|
|
||||||
otxt = p.Pcond.Pc - c
|
otxt = p.Pcond.Pc - c
|
||||||
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
|
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
q.Link = p.Link
|
q.Link = p.Link
|
||||||
p.Link = q
|
p.Link = q
|
||||||
q.As = ABR
|
q.As = ABR
|
||||||
q.To.Type = D_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q.Pcond = p.Pcond
|
q.Pcond = p.Pcond
|
||||||
p.Pcond = q
|
p.Pcond = q
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
q.Link = p.Link
|
q.Link = p.Link
|
||||||
p.Link = q
|
p.Link = q
|
||||||
q.As = ABR
|
q.As = ABR
|
||||||
q.To.Type = D_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q.Pcond = q.Link.Link
|
q.Pcond = q.Link.Link
|
||||||
|
|
||||||
//addnop(p->link);
|
//addnop(p->link);
|
||||||
@ -497,7 +492,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
m = int(o.size)
|
m = int(o.size)
|
||||||
if m == 0 {
|
if m == 0 {
|
||||||
if p.As != ANOP && p.As != AFUNCDATA && p.As != APCDATA {
|
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
|
||||||
ctxt.Diag("zero-width instruction\n%v", p)
|
ctxt.Diag("zero-width instruction\n%v", p)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -516,7 +511,6 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
* lay out the code, emitting code and data relocations.
|
* lay out the code, emitting code and data relocations.
|
||||||
*/
|
*/
|
||||||
if ctxt.Tlsg == nil {
|
if ctxt.Tlsg == nil {
|
||||||
|
|
||||||
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
|
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,43 +544,49 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
|||||||
var s *obj.LSym
|
var s *obj.LSym
|
||||||
|
|
||||||
switch a.Type {
|
switch a.Type {
|
||||||
case D_NONE:
|
case obj.TYPE_NONE:
|
||||||
return C_NONE
|
return C_NONE
|
||||||
|
|
||||||
case D_REG:
|
case obj.TYPE_REG:
|
||||||
return C_REG
|
if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
|
||||||
|
return C_REG
|
||||||
case D_FREG:
|
|
||||||
return C_FREG
|
|
||||||
|
|
||||||
case D_CREG:
|
|
||||||
return C_CREG
|
|
||||||
|
|
||||||
case D_SPR:
|
|
||||||
if a.Offset == D_LR {
|
|
||||||
return C_LR
|
|
||||||
}
|
}
|
||||||
if a.Offset == D_XER {
|
if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
|
||||||
return C_XER
|
return C_FREG
|
||||||
}
|
}
|
||||||
if a.Offset == D_CTR {
|
if REG_C0 <= a.Reg && a.Reg <= REG_C7 || a.Reg == REG_CR {
|
||||||
return C_CTR
|
return C_CREG
|
||||||
}
|
}
|
||||||
return C_SPR
|
if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
|
||||||
|
switch a.Reg {
|
||||||
|
case REG_LR:
|
||||||
|
return C_LR
|
||||||
|
|
||||||
case D_DCR:
|
case REG_XER:
|
||||||
return C_SPR
|
return C_XER
|
||||||
|
|
||||||
case D_FPSCR:
|
case REG_CTR:
|
||||||
return C_FPSCR
|
return C_CTR
|
||||||
|
}
|
||||||
|
|
||||||
case D_MSR:
|
return C_SPR
|
||||||
return C_MSR
|
}
|
||||||
|
|
||||||
case D_OREG:
|
if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
|
||||||
|
return C_SPR
|
||||||
|
}
|
||||||
|
if a.Reg == REG_FPSCR {
|
||||||
|
return C_FPSCR
|
||||||
|
}
|
||||||
|
if a.Reg == REG_MSR {
|
||||||
|
return C_MSR
|
||||||
|
}
|
||||||
|
return C_GOK
|
||||||
|
|
||||||
|
case obj.TYPE_MEM:
|
||||||
switch a.Name {
|
switch a.Name {
|
||||||
case D_EXTERN,
|
case obj.NAME_EXTERN,
|
||||||
D_STATIC:
|
obj.NAME_STATIC:
|
||||||
if a.Sym == nil {
|
if a.Sym == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -596,21 +596,21 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
|||||||
}
|
}
|
||||||
return C_LEXT
|
return C_LEXT
|
||||||
|
|
||||||
case D_AUTO:
|
case obj.NAME_AUTO:
|
||||||
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
|
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
|
||||||
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
|
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
|
||||||
return C_SAUTO
|
return C_SAUTO
|
||||||
}
|
}
|
||||||
return C_LAUTO
|
return C_LAUTO
|
||||||
|
|
||||||
case D_PARAM:
|
case obj.NAME_PARAM:
|
||||||
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
|
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
|
||||||
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
|
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
|
||||||
return C_SAUTO
|
return C_SAUTO
|
||||||
}
|
}
|
||||||
return C_LAUTO
|
return C_LAUTO
|
||||||
|
|
||||||
case D_NONE:
|
case obj.TYPE_NONE:
|
||||||
ctxt.Instoffset = a.Offset
|
ctxt.Instoffset = a.Offset
|
||||||
if ctxt.Instoffset == 0 {
|
if ctxt.Instoffset == 0 {
|
||||||
return C_ZOREG
|
return C_ZOREG
|
||||||
@ -623,18 +623,15 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
|||||||
|
|
||||||
return C_GOK
|
return C_GOK
|
||||||
|
|
||||||
case D_OPT:
|
case obj.TYPE_TEXTSIZE:
|
||||||
ctxt.Instoffset = a.Offset & 31
|
return C_TEXTSIZE
|
||||||
if a.Name == D_NONE {
|
|
||||||
return C_SCON
|
|
||||||
}
|
|
||||||
return C_GOK
|
|
||||||
|
|
||||||
case D_CONST:
|
case obj.TYPE_CONST,
|
||||||
|
obj.TYPE_ADDR:
|
||||||
switch a.Name {
|
switch a.Name {
|
||||||
case D_NONE:
|
case obj.TYPE_NONE:
|
||||||
ctxt.Instoffset = a.Offset
|
ctxt.Instoffset = a.Offset
|
||||||
if a.Reg != NREG {
|
if a.Reg != 0 {
|
||||||
if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG {
|
if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG {
|
||||||
return C_SACON
|
return C_SACON
|
||||||
}
|
}
|
||||||
@ -646,8 +643,8 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
|||||||
|
|
||||||
goto consize
|
goto consize
|
||||||
|
|
||||||
case D_EXTERN,
|
case obj.NAME_EXTERN,
|
||||||
D_STATIC:
|
obj.NAME_STATIC:
|
||||||
s = a.Sym
|
s = a.Sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
break
|
break
|
||||||
@ -662,14 +659,14 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
|||||||
/* not sure why this barfs */
|
/* not sure why this barfs */
|
||||||
return C_LCON
|
return C_LCON
|
||||||
|
|
||||||
case D_AUTO:
|
case obj.NAME_AUTO:
|
||||||
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
|
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
|
||||||
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
|
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
|
||||||
return C_SACON
|
return C_SACON
|
||||||
}
|
}
|
||||||
return C_LACON
|
return C_LACON
|
||||||
|
|
||||||
case D_PARAM:
|
case obj.NAME_PARAM:
|
||||||
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
|
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
|
||||||
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
|
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
|
||||||
return C_SACON
|
return C_SACON
|
||||||
@ -710,7 +707,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
|||||||
}
|
}
|
||||||
return C_DCON
|
return C_DCON
|
||||||
|
|
||||||
case D_BRANCH:
|
case obj.TYPE_BRANCH:
|
||||||
return C_SBRA
|
return C_SBRA
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,7 +756,7 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
|
|||||||
|
|
||||||
a4--
|
a4--
|
||||||
a2 = C_NONE
|
a2 = C_NONE
|
||||||
if p.Reg != NREG {
|
if p.Reg != 0 {
|
||||||
a2 = C_REG
|
a2 = C_REG
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -924,8 +921,7 @@ func buildop(ctxt *obj.Link) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for n = 0; optab[n].as != AXXX; n++ {
|
for n = 0; optab[n].as != obj.AXXX; n++ {
|
||||||
|
|
||||||
}
|
}
|
||||||
sort.Sort(ocmp(optab[:n]))
|
sort.Sort(ocmp(optab[:n]))
|
||||||
for i = 0; i < n; i++ {
|
for i = 0; i < n; i++ {
|
||||||
@ -1295,14 +1291,14 @@ func buildop(ctxt *obj.Link) {
|
|||||||
ASLBMTE,
|
ASLBMTE,
|
||||||
AWORD,
|
AWORD,
|
||||||
ADWORD,
|
ADWORD,
|
||||||
ANOP,
|
obj.ANOP,
|
||||||
ATEXT,
|
obj.ATEXT,
|
||||||
AUNDEF,
|
obj.AUNDEF,
|
||||||
AUSEFIELD,
|
obj.AUSEFIELD,
|
||||||
AFUNCDATA,
|
obj.AFUNCDATA,
|
||||||
APCDATA,
|
obj.APCDATA,
|
||||||
ADUFFZERO,
|
obj.ADUFFZERO,
|
||||||
ADUFFCOPY:
|
obj.ADUFFCOPY:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1322,7 +1318,6 @@ func OP(o uint32, xo uint32) uint32 {
|
|||||||
|
|
||||||
/* the order is dest, a/s, b/imm for both arithmetic and logical operations */
|
/* the order is dest, a/s, b/imm for both arithmetic and logical operations */
|
||||||
func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
|
func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
|
||||||
|
|
||||||
return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
|
return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,7 +1392,6 @@ func oclass(a *obj.Addr) int {
|
|||||||
|
|
||||||
// add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2.
|
// add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2.
|
||||||
func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
|
func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
|
||||||
|
|
||||||
var rel *obj.Reloc
|
var rel *obj.Reloc
|
||||||
|
|
||||||
rel = obj.Addrel(ctxt.Cursym)
|
rel = obj.Addrel(ctxt.Cursym)
|
||||||
@ -1412,7 +1406,6 @@ func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
|
|||||||
* 32-bit masks
|
* 32-bit masks
|
||||||
*/
|
*/
|
||||||
func getmask(m []byte, v uint32) int {
|
func getmask(m []byte, v uint32) int {
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
|
|
||||||
m[1] = 0
|
m[1] = 0
|
||||||
@ -1461,7 +1454,6 @@ func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) {
|
|||||||
* 64-bit masks (rldic etc)
|
* 64-bit masks (rldic etc)
|
||||||
*/
|
*/
|
||||||
func getmask64(m []byte, v uint64) int {
|
func getmask64(m []byte, v uint64) int {
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
|
|
||||||
m[1] = 0
|
m[1] = 0
|
||||||
@ -1534,7 +1526,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
//print("%P => case %d\n", p, o->type);
|
//print("%P => case %d\n", p, o->type);
|
||||||
switch o.type_ {
|
switch o.type_ {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ctxt.Diag("unknown type %d", o.type_)
|
ctxt.Diag("unknown type %d", o.type_)
|
||||||
prasm(p)
|
prasm(p)
|
||||||
@ -1543,8 +1534,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
break
|
break
|
||||||
|
|
||||||
case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
|
case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
|
||||||
if p.To.Reg == REGZERO && p.From.Type == D_CONST {
|
if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
|
||||||
|
|
||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
||||||
//nerrors--;
|
//nerrors--;
|
||||||
@ -1560,7 +1550,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 2: /* int/cr/fp op Rb,[Ra],Rd */
|
case 2: /* int/cr/fp op Rb,[Ra],Rd */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
||||||
@ -1570,7 +1560,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
v = int32(d)
|
v = int32(d)
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
|
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
|
||||||
@ -1589,7 +1579,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
a = OP_ADDIS
|
a = OP_ADDIS
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if int64(int16(d)) != d {
|
if int64(int16(d)) != d {
|
||||||
log.Fatalf("invalid handling of %v", p)
|
log.Fatalf("invalid handling of %v", p)
|
||||||
}
|
}
|
||||||
@ -1601,7 +1590,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
|
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
|
||||||
@ -1618,7 +1607,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 6: /* logical op Rb,[Rs,]Ra; no literal */
|
case 6: /* logical op Rb,[Rs,]Ra; no literal */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
||||||
@ -1626,17 +1615,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 7: /* mov r, soreg ==> stw o(r) */
|
case 7: /* mov r, soreg ==> stw o(r) */
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.To)
|
v = regoff(ctxt, &p.To)
|
||||||
if p.To.Type == D_OREG && p.Reg != NREG {
|
if p.To.Type == obj.TYPE_MEM && p.Reg != 0 {
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
ctxt.Diag("illegal indexed instruction\n%v", p)
|
ctxt.Diag("illegal indexed instruction\n%v", p)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.Reg), uint32(r))
|
o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.Reg), uint32(r))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if int32(int16(v)) != v {
|
if int32(int16(v)) != v {
|
||||||
log.Fatalf("mishandled instruction %v", p)
|
log.Fatalf("mishandled instruction %v", p)
|
||||||
}
|
}
|
||||||
@ -1646,17 +1634,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
|
case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
if p.From.Type == D_OREG && p.Reg != NREG {
|
if p.From.Type == obj.TYPE_MEM && p.Reg != 0 {
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
ctxt.Diag("illegal indexed instruction\n%v", p)
|
ctxt.Diag("illegal indexed instruction\n%v", p)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r))
|
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if int32(int16(v)) != v {
|
if int32(int16(v)) != v {
|
||||||
log.Fatalf("mishandled instruction %v", p)
|
log.Fatalf("mishandled instruction %v", p)
|
||||||
}
|
}
|
||||||
@ -1666,17 +1653,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
|
case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
if p.From.Type == D_OREG && p.Reg != NREG {
|
if p.From.Type == obj.TYPE_MEM && p.Reg != 0 {
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
ctxt.Diag("illegal indexed instruction\n%v", p)
|
ctxt.Diag("illegal indexed instruction\n%v", p)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r))
|
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
|
o1 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
|
||||||
}
|
}
|
||||||
o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
|
o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
|
||||||
@ -1684,7 +1670,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
|
case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
|
||||||
@ -1721,8 +1707,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 12: /* movb r,r (extsb); movw r,r (extsw) */
|
case 12: /* movb r,r (extsb); movw r,r (extsw) */
|
||||||
if p.To.Reg == REGZERO && p.From.Type == D_CONST {
|
if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
|
||||||
|
|
||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
||||||
ctxt.Diag("literal operation on R0\n%v", p)
|
ctxt.Diag("literal operation on R0\n%v", p)
|
||||||
@ -1735,13 +1720,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
if p.As == AMOVW {
|
if p.As == AMOVW {
|
||||||
o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
|
case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
|
||||||
if p.As == AMOVBZ {
|
if p.As == AMOVBZ {
|
||||||
|
|
||||||
o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
|
o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
|
||||||
} else if p.As == AMOVH {
|
} else if p.As == AMOVH {
|
||||||
o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
||||||
@ -1750,14 +1733,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
} else if p.As == AMOVWZ {
|
} else if p.As == AMOVWZ {
|
||||||
o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
|
o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
|
ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
|
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
d = vregoff(ctxt, &p.From3)
|
d = vregoff(ctxt, &p.From3)
|
||||||
@ -1792,11 +1774,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
16: /* bc bo,bi,sbra */
|
16: /* bc bo,bi,sbra */
|
||||||
a = 0
|
a = 0
|
||||||
|
|
||||||
if p.From.Type == D_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
a = int(regoff(ctxt, &p.From))
|
a = int(regoff(ctxt, &p.From))
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
v = 0
|
v = 0
|
||||||
@ -1815,17 +1797,15 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
|
case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
|
||||||
if p.As == ABC || p.As == ABCL {
|
if p.As == ABC || p.As == ABCL {
|
||||||
|
|
||||||
v = regoff(ctxt, &p.To) & 31
|
v = regoff(ctxt, &p.To) & 31
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
v = 20 /* unconditional */
|
v = 20 /* unconditional */
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (D_LR&0x1f)<<16 | ((D_LR>>5)&0x1f)<<11
|
o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
|
||||||
o2 = OPVCC(19, 16, 0, 0)
|
o2 = OPVCC(19, 16, 0, 0)
|
||||||
if p.As == ABL || p.As == ABCL {
|
if p.As == ABL || p.As == ABCL {
|
||||||
o2 |= 1
|
o2 |= 1
|
||||||
@ -1834,14 +1814,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
|
case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
|
||||||
if p.As == ABC || p.As == ABCL {
|
if p.As == ABC || p.As == ABCL {
|
||||||
|
|
||||||
v = regoff(ctxt, &p.From) & 31
|
v = regoff(ctxt, &p.From) & 31
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
v = 20 /* unconditional */
|
v = 20 /* unconditional */
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
switch oclass(&p.To) {
|
switch oclass(&p.To) {
|
||||||
@ -1868,7 +1846,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
o1 = loadu32(int(p.To.Reg), d)
|
o1 = loadu32(int(p.To.Reg), d)
|
||||||
o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
|
o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(int32(d))))
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(int32(d))))
|
||||||
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(d))
|
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(d))
|
||||||
addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
|
addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
|
||||||
@ -1880,24 +1857,23 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
if p.As == AADD && (!(r0iszero != 0 /*TypeKind(100016)*/) && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
|
if p.As == AADD && (!(r0iszero != 0 /*TypeKind(100016)*/) && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
|
||||||
ctxt.Diag("literal operation on R0\n%v", p)
|
ctxt.Diag("literal operation on R0\n%v", p)
|
||||||
}
|
}
|
||||||
o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As)+AEND)), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
|
o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
|
||||||
|
|
||||||
case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
|
case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
|
||||||
if p.To.Reg == REGTMP || p.Reg == REGTMP {
|
if p.To.Reg == REGTMP || p.Reg == REGTMP {
|
||||||
|
|
||||||
ctxt.Diag("cant synthesize large constant\n%v", p)
|
ctxt.Diag("cant synthesize large constant\n%v", p)
|
||||||
}
|
}
|
||||||
d = vregoff(ctxt, &p.From)
|
d = vregoff(ctxt, &p.From)
|
||||||
o1 = loadu32(REGTMP, d)
|
o1 = loadu32(REGTMP, d)
|
||||||
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
|
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r))
|
o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r))
|
||||||
@ -1909,14 +1885,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
|
case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
|
||||||
if p.To.Reg == REGTMP || p.Reg == REGTMP {
|
if p.To.Reg == REGTMP || p.Reg == REGTMP {
|
||||||
|
|
||||||
ctxt.Diag("cant synthesize large constant\n%v", p)
|
ctxt.Diag("cant synthesize large constant\n%v", p)
|
||||||
}
|
}
|
||||||
d = vregoff(ctxt, &p.From)
|
d = vregoff(ctxt, &p.From)
|
||||||
o1 = loadu32(REGTMP, d)
|
o1 = loadu32(REGTMP, d)
|
||||||
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
|
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o3 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r))
|
o3 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r))
|
||||||
@ -1937,7 +1912,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = 63
|
v = 63
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
switch p.As {
|
switch p.As {
|
||||||
@ -1972,12 +1947,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
|
case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
|
||||||
if p.To.Reg == REGTMP {
|
if p.To.Reg == REGTMP {
|
||||||
|
|
||||||
ctxt.Diag("can't synthesize large constant\n%v", p)
|
ctxt.Diag("can't synthesize large constant\n%v", p)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
|
||||||
@ -1991,7 +1965,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
|
case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
|
||||||
if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
|
if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
|
||||||
|
|
||||||
ctxt.Diag("can't synthesize large constant\n%v", p)
|
ctxt.Diag("can't synthesize large constant\n%v", p)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From3)
|
v = regoff(ctxt, &p.From3)
|
||||||
@ -2069,7 +2042,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
o1 = uint32(d >> 32)
|
o1 = uint32(d >> 32)
|
||||||
o2 = uint32(d)
|
o2 = uint32(d)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = uint32(d)
|
o1 = uint32(d)
|
||||||
o2 = uint32(d >> 32)
|
o2 = uint32(d >> 32)
|
||||||
}
|
}
|
||||||
@ -2088,7 +2060,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 32: /* fmul frc,fra,frd */
|
case 32: /* fmul frc,fra,frd */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
|
||||||
@ -2108,7 +2080,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.To)
|
v = regoff(ctxt, &p.To)
|
||||||
|
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
|
||||||
@ -2118,7 +2090,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
|
||||||
@ -2128,7 +2100,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
|
||||||
@ -2147,7 +2119,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
|
case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(r), uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(r), uint32(p.From.Reg))
|
||||||
@ -2155,7 +2127,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 44: /* indexed store */
|
case 44: /* indexed store */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
|
o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
|
||||||
@ -2163,7 +2135,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 45: /* indexed load */
|
case 45: /* indexed load */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
||||||
@ -2174,7 +2146,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 47: /* op Ra, Rd; also op [Ra,] Rd */
|
case 47: /* op Ra, Rd; also op [Ra,] Rd */
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
|
||||||
@ -2182,24 +2154,23 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 48: /* op Rs, Ra */
|
case 48: /* op Rs, Ra */
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
|
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
|
||||||
|
|
||||||
case 49: /* op Rb; op $n, Rb */
|
case 49: /* op Rb; op $n, Rb */
|
||||||
if p.From.Type != D_REG { /* tlbie $L, rB */
|
if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
|
||||||
v = regoff(ctxt, &p.From) & 1
|
v = regoff(ctxt, &p.From) & 1
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg))
|
||||||
}
|
}
|
||||||
|
|
||||||
case 50: /* rem[u] r1[,r2],r3 */
|
case 50: /* rem[u] r1[,r2],r3 */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
v = oprrr(ctxt, int(p.As))
|
v = oprrr(ctxt, int(p.As))
|
||||||
@ -2217,7 +2188,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 51: /* remd[u] r1[,r2],r3 */
|
case 51: /* remd[u] r1[,r2],r3 */
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
|
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
v = oprrr(ctxt, int(p.As))
|
v = oprrr(ctxt, int(p.As))
|
||||||
@ -2236,15 +2207,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
|
|
||||||
case 54: /* mov msr,r1; mov r1, msr*/
|
case 54: /* mov msr,r1; mov r1, msr*/
|
||||||
if oclass(&p.From) == C_REG {
|
if oclass(&p.From) == C_REG {
|
||||||
|
|
||||||
if p.As == AMOVD {
|
if p.As == AMOVD {
|
||||||
o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
|
o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
|
o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
|
o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2255,7 +2223,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.To.Reg), uint32(v)&31)
|
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.To.Reg), uint32(v)&31)
|
||||||
@ -2267,7 +2235,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2279,7 +2247,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
ctxt->diag("illegal shift %ld\n%P", v, p);
|
ctxt->diag("illegal shift %ld\n%P", v, p);
|
||||||
*/
|
*/
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
|
|
||||||
v = 0
|
v = 0
|
||||||
} else if v > 32 {
|
} else if v > 32 {
|
||||||
v = 32
|
v = 32
|
||||||
@ -2289,7 +2256,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
mask[1] = 31
|
mask[1] = 31
|
||||||
v = 32 - v
|
v = 32 - v
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
mask[0] = 0
|
mask[0] = 0
|
||||||
mask[1] = uint8(31 - v)
|
mask[1] = uint8(31 - v)
|
||||||
}
|
}
|
||||||
@ -2303,7 +2269,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
|
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
|
||||||
@ -2312,10 +2278,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
v = regoff(ctxt, &p.From)
|
v = regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r = int(p.Reg)
|
||||||
if r == NREG {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+AEND)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */
|
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */
|
||||||
|
|
||||||
case 60: /* tw to,a,b */
|
case 60: /* tw to,a,b */
|
||||||
r = int(regoff(ctxt, &p.From) & 31)
|
r = int(regoff(ctxt, &p.From) & 31)
|
||||||
@ -2342,41 +2308,34 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
|
o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
|
||||||
|
|
||||||
case 64: /* mtfsf fr[, $m] {,fpcsr} */
|
case 64: /* mtfsf fr[, $m] {,fpcsr} */
|
||||||
if p.From3.Type != D_NONE {
|
if p.From3.Type != obj.TYPE_NONE {
|
||||||
|
|
||||||
v = regoff(ctxt, &p.From3) & 255
|
v = regoff(ctxt, &p.From3) & 255
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
v = 255
|
v = 255
|
||||||
}
|
}
|
||||||
o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
|
o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
|
||||||
|
|
||||||
case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
|
case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
|
||||||
if p.To.Reg == NREG {
|
if p.To.Reg == 0 {
|
||||||
|
|
||||||
ctxt.Diag("must specify FPSCR(n)\n%v", p)
|
ctxt.Diag("must specify FPSCR(n)\n%v", p)
|
||||||
}
|
}
|
||||||
o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12
|
o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12
|
||||||
|
|
||||||
case 66: /* mov spr,r1; mov r1,spr, also dcr */
|
case 66: /* mov spr,r1; mov r1,spr, also dcr */
|
||||||
if p.From.Type == D_REG {
|
if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
v = int32(p.To.Offset)
|
v = int32(p.To.Reg)
|
||||||
if p.To.Type == D_DCR {
|
if REG_DCR0 <= v && v <= REG_DCR0+1023 {
|
||||||
o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
|
o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = OPVCC(31, 467, 0, 0) /* mtspr */
|
o1 = OPVCC(31, 467, 0, 0) /* mtspr */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
v = int32(p.From.Offset)
|
v = int32(p.From.Reg)
|
||||||
if p.From.Type == D_DCR {
|
if REG_DCR0 <= v && v <= REG_DCR0+1023 {
|
||||||
o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
|
o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = OPVCC(31, 339, 0, 0) /* mfspr */
|
o1 = OPVCC(31, 339, 0, 0) /* mfspr */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2384,35 +2343,29 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
|
o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
|
||||||
|
|
||||||
case 67: /* mcrf crfD,crfS */
|
case 67: /* mcrf crfD,crfS */
|
||||||
if p.From.Type != D_CREG || p.From.Reg == NREG || p.To.Type != D_CREG || p.To.Reg == NREG {
|
if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_C0 || REG_C7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_C0 || REG_C7 < p.To.Reg {
|
||||||
|
|
||||||
ctxt.Diag("illegal CR field number\n%v", p)
|
ctxt.Diag("illegal CR field number\n%v", p)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
|
o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
|
||||||
|
|
||||||
case 68: /* mfcr rD; mfocrf CRM,rD */
|
case 68: /* mfcr rD; mfocrf CRM,rD */
|
||||||
if p.From.Type == D_CREG && p.From.Reg != NREG {
|
if p.From.Type == obj.TYPE_REG && REG_C0 <= p.From.Reg && p.From.Reg <= REG_C7 {
|
||||||
|
|
||||||
v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
|
v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
|
||||||
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
|
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
|
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
|
||||||
}
|
}
|
||||||
|
|
||||||
case 69: /* mtcrf CRM,rS */
|
case 69: /* mtcrf CRM,rS */
|
||||||
if p.From3.Type != D_NONE {
|
if p.From3.Type != obj.TYPE_NONE {
|
||||||
|
if p.To.Reg != 0 {
|
||||||
if p.To.Reg != NREG {
|
|
||||||
ctxt.Diag("can't use both mask and CR(n)\n%v", p)
|
ctxt.Diag("can't use both mask and CR(n)\n%v", p)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From3) & 0xff
|
v = regoff(ctxt, &p.From3) & 0xff
|
||||||
} else {
|
} else {
|
||||||
|
if p.To.Reg == 0 {
|
||||||
if p.To.Reg == NREG {
|
|
||||||
v = 0xff /* CR */
|
v = 0xff /* CR */
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
|
v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2420,21 +2373,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
|
o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
|
||||||
|
|
||||||
case 70: /* [f]cmp r,r,cr*/
|
case 70: /* [f]cmp r,r,cr*/
|
||||||
if p.Reg == NREG {
|
if p.Reg == 0 {
|
||||||
|
|
||||||
r = 0
|
r = 0
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
r = (int(p.Reg) & 7) << 2
|
r = (int(p.Reg) & 7) << 2
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
|
||||||
|
|
||||||
case 71: /* cmp[l] r,i,cr*/
|
case 71: /* cmp[l] r,i,cr*/
|
||||||
if p.Reg == NREG {
|
if p.Reg == 0 {
|
||||||
|
|
||||||
r = 0
|
r = 0
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
r = (int(p.Reg) & 7) << 2
|
r = (int(p.Reg) & 7) << 2
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff
|
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff
|
||||||
@ -2443,23 +2392,20 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.From.Reg), 0, uint32(p.To.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.From.Reg), 0, uint32(p.To.Reg))
|
||||||
|
|
||||||
case 73: /* mcrfs crfD,crfS */
|
case 73: /* mcrfs crfD,crfS */
|
||||||
if p.From.Type != D_FPSCR || p.From.Reg == NREG || p.To.Type != D_CREG || p.To.Reg == NREG {
|
if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_C0 || REG_C7 < p.To.Reg {
|
||||||
|
|
||||||
ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
|
ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
|
||||||
}
|
}
|
||||||
o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
|
o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
|
||||||
|
|
||||||
case 77: /* syscall $scon, syscall Rx */
|
case 77: /* syscall $scon, syscall Rx */
|
||||||
if p.From.Type == D_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
|
|
||||||
if p.From.Offset > BIG || p.From.Offset < -BIG {
|
if p.From.Offset > BIG || p.From.Offset < -BIG {
|
||||||
ctxt.Diag("illegal syscall, sysnum too large: %v", p)
|
ctxt.Diag("illegal syscall, sysnum too large: %v", p)
|
||||||
}
|
}
|
||||||
o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
|
o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
|
||||||
} else if p.From.Type == D_REG {
|
} else if p.From.Type == obj.TYPE_REG {
|
||||||
o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
|
o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ctxt.Diag("illegal syscall: %v", p)
|
ctxt.Diag("illegal syscall: %v", p)
|
||||||
o1 = 0x7fe00008 // trap always
|
o1 = 0x7fe00008 // trap always
|
||||||
}
|
}
|
||||||
@ -3046,21 +2992,21 @@ func opirr(ctxt *obj.Link, a int) int32 {
|
|||||||
return int32(OPVCC(12, 0, 0, 0))
|
return int32(OPVCC(12, 0, 0, 0))
|
||||||
case AADDCCC:
|
case AADDCCC:
|
||||||
return int32(OPVCC(13, 0, 0, 0))
|
return int32(OPVCC(13, 0, 0, 0))
|
||||||
case AADD + AEND:
|
case AADD + ALAST:
|
||||||
return int32(OPVCC(15, 0, 0, 0)) /* ADDIS/CAU */
|
return int32(OPVCC(15, 0, 0, 0)) /* ADDIS/CAU */
|
||||||
|
|
||||||
case AANDCC:
|
case AANDCC:
|
||||||
return int32(OPVCC(28, 0, 0, 0))
|
return int32(OPVCC(28, 0, 0, 0))
|
||||||
case AANDCC + AEND:
|
case AANDCC + ALAST:
|
||||||
return int32(OPVCC(29, 0, 0, 0)) /* ANDIS./ANDIU. */
|
return int32(OPVCC(29, 0, 0, 0)) /* ANDIS./ANDIU. */
|
||||||
|
|
||||||
case ABR:
|
case ABR:
|
||||||
return int32(OPVCC(18, 0, 0, 0))
|
return int32(OPVCC(18, 0, 0, 0))
|
||||||
case ABL:
|
case ABL:
|
||||||
return int32(OPVCC(18, 0, 0, 0) | 1)
|
return int32(OPVCC(18, 0, 0, 0) | 1)
|
||||||
case ADUFFZERO:
|
case obj.ADUFFZERO:
|
||||||
return int32(OPVCC(18, 0, 0, 0) | 1)
|
return int32(OPVCC(18, 0, 0, 0) | 1)
|
||||||
case ADUFFCOPY:
|
case obj.ADUFFCOPY:
|
||||||
return int32(OPVCC(18, 0, 0, 0) | 1)
|
return int32(OPVCC(18, 0, 0, 0) | 1)
|
||||||
case ABC:
|
case ABC:
|
||||||
return int32(OPVCC(16, 0, 0, 0))
|
return int32(OPVCC(16, 0, 0, 0))
|
||||||
@ -3100,7 +3046,7 @@ func opirr(ctxt *obj.Link, a int) int32 {
|
|||||||
|
|
||||||
case AOR:
|
case AOR:
|
||||||
return int32(OPVCC(24, 0, 0, 0))
|
return int32(OPVCC(24, 0, 0, 0))
|
||||||
case AOR + AEND:
|
case AOR + ALAST:
|
||||||
return int32(OPVCC(25, 0, 0, 0)) /* ORIS/ORIU */
|
return int32(OPVCC(25, 0, 0, 0)) /* ORIS/ORIU */
|
||||||
|
|
||||||
case ARLWMI:
|
case ARLWMI:
|
||||||
@ -3152,7 +3098,7 @@ func opirr(ctxt *obj.Link, a int) int32 {
|
|||||||
|
|
||||||
case AXOR:
|
case AXOR:
|
||||||
return int32(OPVCC(26, 0, 0, 0)) /* XORIL */
|
return int32(OPVCC(26, 0, 0, 0)) /* XORIL */
|
||||||
case AXOR + AEND:
|
case AXOR + ALAST:
|
||||||
return int32(OPVCC(27, 0, 0, 0)) /* XORIU */
|
return int32(OPVCC(27, 0, 0, 0)) /* XORIU */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3164,7 +3110,6 @@ func opirr(ctxt *obj.Link, a int) int32 {
|
|||||||
* load o(a),d
|
* load o(a),d
|
||||||
*/
|
*/
|
||||||
func opload(ctxt *obj.Link, a int) int32 {
|
func opload(ctxt *obj.Link, a int) int32 {
|
||||||
|
|
||||||
switch a {
|
switch a {
|
||||||
case AMOVD:
|
case AMOVD:
|
||||||
return int32(OPVCC(58, 0, 0, 0)) /* ld */
|
return int32(OPVCC(58, 0, 0, 0)) /* ld */
|
||||||
@ -3214,7 +3159,6 @@ func opload(ctxt *obj.Link, a int) int32 {
|
|||||||
* indexed load a(b),d
|
* indexed load a(b),d
|
||||||
*/
|
*/
|
||||||
func oploadx(ctxt *obj.Link, a int) int32 {
|
func oploadx(ctxt *obj.Link, a int) int32 {
|
||||||
|
|
||||||
switch a {
|
switch a {
|
||||||
case AMOVWZ:
|
case AMOVWZ:
|
||||||
return int32(OPVCC(31, 23, 0, 0)) /* lwzx */
|
return int32(OPVCC(31, 23, 0, 0)) /* lwzx */
|
||||||
@ -3274,7 +3218,6 @@ func oploadx(ctxt *obj.Link, a int) int32 {
|
|||||||
* store s,o(d)
|
* store s,o(d)
|
||||||
*/
|
*/
|
||||||
func opstore(ctxt *obj.Link, a int) int32 {
|
func opstore(ctxt *obj.Link, a int) int32 {
|
||||||
|
|
||||||
switch a {
|
switch a {
|
||||||
case AMOVB,
|
case AMOVB,
|
||||||
AMOVBZ:
|
AMOVBZ:
|
||||||
@ -3325,7 +3268,6 @@ func opstore(ctxt *obj.Link, a int) int32 {
|
|||||||
* indexed store s,a(b)
|
* indexed store s,a(b)
|
||||||
*/
|
*/
|
||||||
func opstorex(ctxt *obj.Link, a int) int32 {
|
func opstorex(ctxt *obj.Link, a int) int32 {
|
||||||
|
|
||||||
switch a {
|
switch a {
|
||||||
case AMOVB,
|
case AMOVB,
|
||||||
AMOVBZ:
|
AMOVBZ:
|
||||||
|
@ -43,7 +43,6 @@ const (
|
|||||||
// %A int Opcodes (instruction mnemonics)
|
// %A int Opcodes (instruction mnemonics)
|
||||||
//
|
//
|
||||||
// %D Addr* Addresses (instruction operands)
|
// %D Addr* Addresses (instruction operands)
|
||||||
// Flags: "%lD": seperate the high and low words of a constant by "-"
|
|
||||||
//
|
//
|
||||||
// %P Prog* Instructions
|
// %P Prog* Instructions
|
||||||
//
|
//
|
||||||
@ -59,49 +58,34 @@ func Pconv(p *obj.Prog) string {
|
|||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
var a int
|
var a int
|
||||||
var ch int
|
|
||||||
|
|
||||||
a = int(p.As)
|
a = int(p.As)
|
||||||
|
|
||||||
if a == ADATA || a == AINIT || a == ADYNT {
|
str = ""
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
|
if a == obj.ADATA {
|
||||||
} else if a == ATEXT {
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
|
||||||
if p.Reg != 0 {
|
} else if a == obj.ATEXT || a == obj.AGLOBL {
|
||||||
str = fmt.Sprintf("%.5d (%v) %v %v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, fmtLong, &p.To))
|
if p.From3.Offset != 0 {
|
||||||
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
|
||||||
} else {
|
} else {
|
||||||
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
||||||
str = fmt.Sprintf("%.5d (%v) %v %v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To))
|
|
||||||
}
|
|
||||||
} else if a == AGLOBL {
|
|
||||||
if p.Reg != 0 {
|
|
||||||
str = fmt.Sprintf("%.5d (%v) %v %v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("%.5d (%v) %v %v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if p.Mark&NOSCHED != 0 {
|
if p.Mark&NOSCHED != 0 {
|
||||||
str += fmt.Sprintf("*")
|
str += fmt.Sprintf("*")
|
||||||
}
|
}
|
||||||
if p.Reg == NREG && p.From3.Type == D_NONE {
|
if p.Reg == 0 && p.From3.Type == obj.TYPE_NONE {
|
||||||
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
||||||
} else if a != ATEXT && p.From.Type == D_OREG {
|
} else if a != obj.ATEXT && p.From.Type == obj.TYPE_MEM {
|
||||||
str += fmt.Sprintf("%.5d (%v)\t%v\t%d(R%d+R%d),%v", p.Pc, p.Line(), Aconv(a), p.From.Offset, p.From.Reg, p.Reg, Dconv(p, 0, &p.To))
|
str += fmt.Sprintf("%.5d (%v)\t%v\t%d(%v+%v),%v", p.Pc, p.Line(), Aconv(a), p.From.Offset, Rconv(int(p.From.Reg)), Rconv(int(p.Reg)), Dconv(p, 0, &p.To))
|
||||||
} else if p.To.Type == D_OREG {
|
} else if p.To.Type == obj.TYPE_MEM {
|
||||||
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%d(R%d+R%d)", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.To.Offset, p.To.Reg, p.Reg)
|
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%d(%v+%v)", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.To.Offset, Rconv(int(p.To.Reg)), Rconv(int(p.Reg)))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str += fmt.Sprintf("%.5d (%v)\t%v\t%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From))
|
str += fmt.Sprintf("%.5d (%v)\t%v\t%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From))
|
||||||
if p.Reg != NREG {
|
if p.Reg != 0 {
|
||||||
ch = 'R'
|
str += fmt.Sprintf(",%v", Rconv(int(p.Reg)))
|
||||||
if p.From.Type == D_FREG {
|
|
||||||
ch = 'F'
|
|
||||||
}
|
|
||||||
str += fmt.Sprintf(",%c%d", ch, p.Reg)
|
|
||||||
}
|
}
|
||||||
|
if p.From3.Type != obj.TYPE_NONE {
|
||||||
if p.From3.Type != D_NONE {
|
|
||||||
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.From3))
|
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.From3))
|
||||||
}
|
}
|
||||||
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.To))
|
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.To))
|
||||||
@ -122,7 +106,7 @@ func Aconv(a int) string {
|
|||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
s = "???"
|
s = "???"
|
||||||
if a >= AXXX && a < ALAST {
|
if a >= obj.AXXX && a < ALAST {
|
||||||
s = Anames[a]
|
s = Anames[a]
|
||||||
}
|
}
|
||||||
fp += s
|
fp += s
|
||||||
@ -135,126 +119,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
|
|||||||
|
|
||||||
var v int32
|
var v int32
|
||||||
|
|
||||||
if flag&fmtLong != 0 /*untyped*/ {
|
|
||||||
if a.Type == D_CONST {
|
|
||||||
str = fmt.Sprintf("$%d-%d", int32(a.Offset), int32(a.Offset>>32))
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// ATEXT dst is not constant
|
|
||||||
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
|
|
||||||
}
|
|
||||||
|
|
||||||
goto ret
|
|
||||||
}
|
|
||||||
|
|
||||||
switch a.Type {
|
switch a.Type {
|
||||||
default:
|
default:
|
||||||
str = fmt.Sprintf("GOK-type(%d)", a.Type)
|
str = fmt.Sprintf("GOK-type(%d)", a.Type)
|
||||||
|
|
||||||
case D_NONE:
|
case obj.TYPE_NONE:
|
||||||
str = ""
|
str = ""
|
||||||
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil {
|
if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil {
|
||||||
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg)
|
str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_CONST,
|
case obj.TYPE_CONST,
|
||||||
D_DCONST:
|
obj.TYPE_ADDR:
|
||||||
if a.Reg != NREG {
|
if a.Reg != 0 {
|
||||||
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg)
|
str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("$%v", Mconv(a))
|
str = fmt.Sprintf("$%v", Mconv(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_OREG:
|
case obj.TYPE_TEXTSIZE:
|
||||||
if a.Reg != NREG {
|
if a.U.Argsize == obj.ArgsSizeUnknown {
|
||||||
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg)
|
str = fmt.Sprintf("$%d", a.Offset)
|
||||||
} else {
|
} else {
|
||||||
|
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
case obj.TYPE_MEM:
|
||||||
|
if a.Reg != 0 {
|
||||||
|
str = fmt.Sprintf("%v(%v)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
|
} else {
|
||||||
str = fmt.Sprintf("%v", Mconv(a))
|
str = fmt.Sprintf("%v", Mconv(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_REG:
|
case obj.TYPE_REG:
|
||||||
str = fmt.Sprintf("R%d", a.Reg)
|
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
|
||||||
if a.Name != D_NONE || a.Sym != nil {
|
if a.Name != obj.TYPE_NONE || a.Sym != nil {
|
||||||
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
|
str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_FREG:
|
case obj.TYPE_BRANCH:
|
||||||
str = fmt.Sprintf("F%d", a.Reg)
|
|
||||||
if a.Name != D_NONE || a.Sym != nil {
|
|
||||||
str = fmt.Sprintf("%v(F%d)(REG)", Mconv(a), a.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
case D_CREG:
|
|
||||||
if a.Reg == NREG {
|
|
||||||
str = "CR"
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("CR%d", a.Reg)
|
|
||||||
}
|
|
||||||
if a.Name != D_NONE || a.Sym != nil {
|
|
||||||
str = fmt.Sprintf("%v(C%d)(REG)", Mconv(a), a.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
case D_SPR:
|
|
||||||
if a.Name == D_NONE && a.Sym == nil {
|
|
||||||
switch uint32(a.Offset) {
|
|
||||||
case D_XER:
|
|
||||||
str = fmt.Sprintf("XER")
|
|
||||||
case D_LR:
|
|
||||||
str = fmt.Sprintf("LR")
|
|
||||||
case D_CTR:
|
|
||||||
str = fmt.Sprintf("CTR")
|
|
||||||
default:
|
|
||||||
str = fmt.Sprintf("SPR(%d)", a.Offset)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
str = fmt.Sprintf("SPR-GOK(%d)", a.Reg)
|
|
||||||
if a.Name != D_NONE || a.Sym != nil {
|
|
||||||
str = fmt.Sprintf("%v(SPR-GOK%d)(REG)", Mconv(a), a.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
case D_DCR:
|
|
||||||
if a.Name == D_NONE && a.Sym == nil {
|
|
||||||
str = fmt.Sprintf("DCR(%d)", a.Offset)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
str = fmt.Sprintf("DCR-GOK(%d)", a.Reg)
|
|
||||||
if a.Name != D_NONE || a.Sym != nil {
|
|
||||||
str = fmt.Sprintf("%v(DCR-GOK%d)(REG)", Mconv(a), a.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
case D_OPT:
|
|
||||||
str = fmt.Sprintf("OPT(%d)", a.Reg)
|
|
||||||
|
|
||||||
case D_FPSCR:
|
|
||||||
if a.Reg == NREG {
|
|
||||||
str = "FPSCR"
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("FPSCR(%d)", a.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
case D_MSR:
|
|
||||||
str = fmt.Sprintf("MSR")
|
|
||||||
|
|
||||||
case D_BRANCH:
|
|
||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
v = int32(p.Pcond.Pc)
|
v = int32(p.Pcond.Pc)
|
||||||
|
|
||||||
//if(v >= INITTEXT)
|
//if(v >= INITTEXT)
|
||||||
// v -= INITTEXT-HEADR;
|
// v -= INITTEXT-HEADR;
|
||||||
if a.Sym != nil {
|
if a.Sym != nil {
|
||||||
|
|
||||||
str = fmt.Sprintf("%s+%.5x(BRANCH)", a.Sym.Name, uint32(v))
|
str = fmt.Sprintf("%s+%.5x(BRANCH)", a.Sym.Name, uint32(v))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%.5x(BRANCH)", uint32(v))
|
str = fmt.Sprintf("%.5x(BRANCH)", uint32(v))
|
||||||
}
|
}
|
||||||
} else if a.U.Branch != nil {
|
} else if a.U.Branch != nil {
|
||||||
@ -262,20 +173,18 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
|
|||||||
} else if a.Sym != nil {
|
} else if a.Sym != nil {
|
||||||
str = fmt.Sprintf("%s+%d(APC)", a.Sym.Name, a.Offset)
|
str = fmt.Sprintf("%s+%d(APC)", a.Sym.Name, a.Offset)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%d(APC)", a.Offset)
|
str = fmt.Sprintf("%d(APC)", a.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
|
//sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
|
||||||
case D_FCONST:
|
case obj.TYPE_FCONST:
|
||||||
str = fmt.Sprintf("$%.17g", a.U.Dval)
|
str = fmt.Sprintf("$%.17g", a.U.Dval)
|
||||||
|
|
||||||
case D_SCONST:
|
case obj.TYPE_SCONST:
|
||||||
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
ret:
|
|
||||||
fp += str
|
fp += str
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
@ -298,43 +207,38 @@ func Mconv(a *obj.Addr) string {
|
|||||||
// goto out;
|
// goto out;
|
||||||
//}
|
//}
|
||||||
switch a.Name {
|
switch a.Name {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
str = fmt.Sprintf("GOK-name(%d)", a.Name)
|
str = fmt.Sprintf("GOK-name(%d)", a.Name)
|
||||||
|
|
||||||
case D_NONE:
|
case obj.TYPE_NONE:
|
||||||
l = int32(a.Offset)
|
l = int32(a.Offset)
|
||||||
if int64(l) != a.Offset {
|
if int64(l) != a.Offset {
|
||||||
str = fmt.Sprintf("0x%x", uint64(a.Offset))
|
str = fmt.Sprintf("0x%x", uint64(a.Offset))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%d", a.Offset)
|
str = fmt.Sprintf("%d", a.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_EXTERN:
|
case obj.NAME_EXTERN:
|
||||||
if a.Offset != 0 {
|
if a.Offset != 0 {
|
||||||
str = fmt.Sprintf("%s+%d(SB)", s.Name, a.Offset)
|
str = fmt.Sprintf("%s+%d(SB)", s.Name, a.Offset)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%s(SB)", s.Name)
|
str = fmt.Sprintf("%s(SB)", s.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_STATIC:
|
case obj.NAME_STATIC:
|
||||||
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, a.Offset)
|
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, a.Offset)
|
||||||
|
|
||||||
case D_AUTO:
|
case obj.NAME_AUTO:
|
||||||
if s == nil {
|
if s == nil {
|
||||||
str = fmt.Sprintf("%d(SP)", -a.Offset)
|
str = fmt.Sprintf("%d(SP)", -a.Offset)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%s-%d(SP)", s.Name, -a.Offset)
|
str = fmt.Sprintf("%s-%d(SP)", s.Name, -a.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_PARAM:
|
case obj.NAME_PARAM:
|
||||||
if s == nil {
|
if s == nil {
|
||||||
str = fmt.Sprintf("%d(FP)", a.Offset)
|
str = fmt.Sprintf("%d(FP)", a.Offset)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%s+%d(FP)", s.Name, a.Offset)
|
str = fmt.Sprintf("%s+%d(FP)", s.Name, a.Offset)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -346,16 +250,61 @@ func Mconv(a *obj.Addr) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Rconv(r int) string {
|
func Rconv(r int) string {
|
||||||
var str string
|
|
||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
if r < NREG {
|
if r == 0 {
|
||||||
str = fmt.Sprintf("r%d", r)
|
fp += "NONE"
|
||||||
} else {
|
return fp
|
||||||
|
|
||||||
str = fmt.Sprintf("f%d", r-NREG)
|
|
||||||
}
|
}
|
||||||
fp += str
|
if REG_R0 <= r && r <= REG_R31 {
|
||||||
|
fp += fmt.Sprintf("R%d", r-REG_R0)
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if REG_F0 <= r && r <= REG_F31 {
|
||||||
|
fp += fmt.Sprintf("F%d", r-REG_F0)
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if REG_C0 <= r && r <= REG_C7 {
|
||||||
|
fp += fmt.Sprintf("C%d", r-REG_C0)
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if r == REG_CR {
|
||||||
|
fp += "CR"
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if REG_SPR0 <= r && r <= REG_SPR0+1023 {
|
||||||
|
switch r {
|
||||||
|
case REG_XER:
|
||||||
|
fp += "XER"
|
||||||
|
return fp
|
||||||
|
|
||||||
|
case REG_LR:
|
||||||
|
fp += "LR"
|
||||||
|
return fp
|
||||||
|
|
||||||
|
case REG_CTR:
|
||||||
|
fp += "CTR"
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
|
||||||
|
fp += fmt.Sprintf("SPR(%d)", r-REG_SPR0)
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
|
||||||
|
if REG_DCR0 <= r && r <= REG_DCR0+1023 {
|
||||||
|
fp += fmt.Sprintf("DCR(%d)", r-REG_DCR0)
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if r == REG_FPSCR {
|
||||||
|
fp += "FPSCR"
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
if r == REG_MSR {
|
||||||
|
fp += "MSR"
|
||||||
|
return fp
|
||||||
|
}
|
||||||
|
|
||||||
|
fp += fmt.Sprintf("badreg(%d)", r)
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,50 +36,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
var zprg = obj.Prog{
|
|
||||||
As: AGOK,
|
|
||||||
Reg: NREG,
|
|
||||||
From: obj.Addr{
|
|
||||||
Name: D_NONE,
|
|
||||||
Type: D_NONE,
|
|
||||||
Reg: NREG,
|
|
||||||
},
|
|
||||||
From3: obj.Addr{
|
|
||||||
Name: D_NONE,
|
|
||||||
Type: D_NONE,
|
|
||||||
Reg: NREG,
|
|
||||||
},
|
|
||||||
To: obj.Addr{
|
|
||||||
Name: D_NONE,
|
|
||||||
Type: D_NONE,
|
|
||||||
Reg: NREG,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func symtype(a *obj.Addr) int {
|
|
||||||
return int(a.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isdata(p *obj.Prog) bool {
|
|
||||||
return p.As == ADATA || p.As == AGLOBL
|
|
||||||
}
|
|
||||||
|
|
||||||
func iscall(p *obj.Prog) bool {
|
|
||||||
return p.As == ABL
|
|
||||||
}
|
|
||||||
|
|
||||||
func datasize(p *obj.Prog) int {
|
|
||||||
return int(p.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func textflag(p *obj.Prog) int {
|
|
||||||
return int(p.Reg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func settextflag(p *obj.Prog, f int) {
|
|
||||||
p.Reg = uint8(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
var literal string
|
var literal string
|
||||||
var s *obj.LSym
|
var s *obj.LSym
|
||||||
@ -87,25 +43,23 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
p.From.Class = 0
|
p.From.Class = 0
|
||||||
p.To.Class = 0
|
p.To.Class = 0
|
||||||
|
|
||||||
// Rewrite BR/BL to symbol as D_BRANCH.
|
// Rewrite BR/BL to symbol as TYPE_BRANCH.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
|
||||||
case ABR,
|
case ABR,
|
||||||
ABL,
|
ABL,
|
||||||
ARETURN,
|
ARETURN,
|
||||||
ADUFFZERO,
|
obj.ADUFFZERO,
|
||||||
ADUFFCOPY:
|
obj.ADUFFCOPY:
|
||||||
if p.To.Sym != nil {
|
if p.To.Sym != nil {
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite float constants to values stored in memory.
|
// Rewrite float constants to values stored in memory.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
|
||||||
case AFMOVS:
|
case AFMOVS:
|
||||||
if p.From.Type == D_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
var i32 uint32
|
var i32 uint32
|
||||||
var f32 float32
|
var f32 float32
|
||||||
f32 = float32(p.From.U.Dval)
|
f32 = float32(p.From.U.Dval)
|
||||||
@ -113,56 +67,54 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
literal = fmt.Sprintf("$f32.%08x", i32)
|
literal = fmt.Sprintf("$f32.%08x", i32)
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
s = obj.Linklookup(ctxt, literal, 0)
|
||||||
s.Size = 4
|
s.Size = 4
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
p.From.Name = D_EXTERN
|
p.From.Name = obj.NAME_EXTERN
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
case AFMOVD:
|
case AFMOVD:
|
||||||
if p.From.Type == D_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
var i64 uint64
|
var i64 uint64
|
||||||
i64 = math.Float64bits(p.From.U.Dval)
|
i64 = math.Float64bits(p.From.U.Dval)
|
||||||
literal = fmt.Sprintf("$f64.%016x", i64)
|
literal = fmt.Sprintf("$f64.%016x", i64)
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
s = obj.Linklookup(ctxt, literal, 0)
|
||||||
s.Size = 8
|
s.Size = 8
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
p.From.Name = D_EXTERN
|
p.From.Name = obj.NAME_EXTERN
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put >32-bit constants in memory and load them
|
// Put >32-bit constants in memory and load them
|
||||||
case AMOVD:
|
case AMOVD:
|
||||||
if p.From.Type == D_CONST && p.From.Name == D_NONE && p.From.Reg == NREG && int64(int32(p.From.Offset)) != p.From.Offset {
|
if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset {
|
||||||
|
|
||||||
literal = fmt.Sprintf("$i64.%016x", uint64(p.From.Offset))
|
literal = fmt.Sprintf("$i64.%016x", uint64(p.From.Offset))
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
s = obj.Linklookup(ctxt, literal, 0)
|
||||||
s.Size = 8
|
s.Size = 8
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
p.From.Name = D_EXTERN
|
p.From.Name = obj.NAME_EXTERN
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite SUB constants into ADD.
|
// Rewrite SUB constants into ADD.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
|
||||||
case ASUBC:
|
case ASUBC:
|
||||||
if p.From.Type == D_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
p.From.Offset = -p.From.Offset
|
p.From.Offset = -p.From.Offset
|
||||||
p.As = AADDC
|
p.As = AADDC
|
||||||
}
|
}
|
||||||
|
|
||||||
case ASUBCCC:
|
case ASUBCCC:
|
||||||
if p.From.Type == D_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
p.From.Offset = -p.From.Offset
|
p.From.Offset = -p.From.Offset
|
||||||
p.As = AADDCCC
|
p.As = AADDCCC
|
||||||
}
|
}
|
||||||
|
|
||||||
case ASUB:
|
case ASUB:
|
||||||
if p.From.Type == D_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
p.From.Offset = -p.From.Offset
|
p.From.Offset = -p.From.Offset
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
}
|
}
|
||||||
@ -171,20 +123,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsetextconst(arg int64, textstksiz *int64, textarg *int64) {
|
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
*textstksiz = arg & 0xffffffff
|
|
||||||
if *textstksiz&0x80000000 != 0 {
|
|
||||||
*textstksiz = -(-*textstksiz & 0xffffffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
*textarg = (arg >> 32) & 0xffffffff
|
|
||||||
if *textarg&0x80000000 != 0 {
|
|
||||||
*textarg = 0
|
|
||||||
}
|
|
||||||
*textarg = (*textarg + 7) &^ 7
|
|
||||||
}
|
|
||||||
|
|
||||||
func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|
||||||
var p *obj.Prog
|
var p *obj.Prog
|
||||||
var q *obj.Prog
|
var q *obj.Prog
|
||||||
var p1 *obj.Prog
|
var p1 *obj.Prog
|
||||||
@ -194,7 +133,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
var mov int
|
var mov int
|
||||||
var aoffset int
|
var aoffset int
|
||||||
var textstksiz int64
|
var textstksiz int64
|
||||||
var textarg int64
|
|
||||||
var autosize int32
|
var autosize int32
|
||||||
|
|
||||||
if ctxt.Symmorestack[0] == nil {
|
if ctxt.Symmorestack[0] == nil {
|
||||||
@ -210,9 +148,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p = cursym.Text
|
p = cursym.Text
|
||||||
parsetextconst(p.To.Offset, &textstksiz, &textarg)
|
textstksiz = p.To.Offset
|
||||||
|
|
||||||
cursym.Args = int32(p.To.Offset >> 32)
|
cursym.Args = p.To.U.Argsize
|
||||||
cursym.Locals = int32(textstksiz)
|
cursym.Locals = int32(textstksiz)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -222,7 +160,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
* expand BECOME pseudo
|
* expand BECOME pseudo
|
||||||
*/
|
*/
|
||||||
if ctxt.Debugvlog != 0 {
|
if ctxt.Debugvlog != 0 {
|
||||||
|
|
||||||
fmt.Fprintf(ctxt.Bso, "%5.2f noops\n", obj.Cputime())
|
fmt.Fprintf(ctxt.Bso, "%5.2f noops\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
obj.Bflush(ctxt.Bso)
|
obj.Bflush(ctxt.Bso)
|
||||||
@ -231,7 +168,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p = cursym.Text; p != nil; p = p.Link {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
/* too hard, just leave alone */
|
/* too hard, just leave alone */
|
||||||
case ATEXT:
|
case obj.ATEXT:
|
||||||
q = p
|
q = p
|
||||||
|
|
||||||
p.Mark |= LABEL | LEAF | SYNC
|
p.Mark |= LABEL | LEAF | SYNC
|
||||||
@ -241,7 +178,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
case ANOR:
|
case ANOR:
|
||||||
q = p
|
q = p
|
||||||
if p.To.Type == D_REG {
|
if p.To.Type == obj.TYPE_REG {
|
||||||
if p.To.Reg == REGZERO {
|
if p.To.Reg == REGZERO {
|
||||||
p.Mark |= LABEL | SYNC
|
p.Mark |= LABEL | SYNC
|
||||||
}
|
}
|
||||||
@ -284,24 +221,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
AMOVWZ,
|
AMOVWZ,
|
||||||
AMOVD:
|
AMOVD:
|
||||||
q = p
|
q = p
|
||||||
switch p.From.Type {
|
if p.From.Reg >= REG_SPECIAL || p.To.Reg >= REG_SPECIAL {
|
||||||
case D_MSR,
|
|
||||||
D_SPR,
|
|
||||||
D_FPSCR,
|
|
||||||
D_CREG,
|
|
||||||
D_DCR:
|
|
||||||
p.Mark |= LABEL | SYNC
|
p.Mark |= LABEL | SYNC
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.To.Type {
|
|
||||||
case D_MSR,
|
|
||||||
D_SPR,
|
|
||||||
D_FPSCR,
|
|
||||||
D_CREG,
|
|
||||||
D_DCR:
|
|
||||||
p.Mark |= LABEL | SYNC
|
|
||||||
}
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case AFABS,
|
case AFABS,
|
||||||
@ -346,8 +268,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
case ABL,
|
case ABL,
|
||||||
ABCL,
|
ABCL,
|
||||||
ADUFFZERO,
|
obj.ADUFFZERO,
|
||||||
ADUFFCOPY:
|
obj.ADUFFCOPY:
|
||||||
cursym.Text.Mark &^= LEAF
|
cursym.Text.Mark &^= LEAF
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
@ -365,7 +287,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
q = p
|
q = p
|
||||||
q1 = p.Pcond
|
q1 = p.Pcond
|
||||||
if q1 != nil {
|
if q1 != nil {
|
||||||
for q1.As == ANOP {
|
for q1.As == obj.ANOP {
|
||||||
q1 = q1.Link
|
q1 = q1.Link
|
||||||
p.Pcond = q1
|
p.Pcond = q1
|
||||||
}
|
}
|
||||||
@ -374,7 +296,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
q1.Mark |= LABEL
|
q1.Mark |= LABEL
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
p.Mark |= LABEL
|
p.Mark |= LABEL
|
||||||
}
|
}
|
||||||
q1 = p.Link
|
q1 = p.Link
|
||||||
@ -396,7 +317,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case ANOP:
|
case obj.ANOP:
|
||||||
q1 = p.Link
|
q1 = p.Link
|
||||||
q.Link = q1 /* q is non-nop */
|
q.Link = q1 /* q is non-nop */
|
||||||
q1.Mark |= p.Mark
|
q1.Mark |= p.Mark
|
||||||
@ -412,7 +333,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p = cursym.Text; p != nil; p = p.Link {
|
||||||
o = int(p.As)
|
o = int(p.As)
|
||||||
switch o {
|
switch o {
|
||||||
case ATEXT:
|
case obj.ATEXT:
|
||||||
mov = AMOVD
|
mov = AMOVD
|
||||||
aoffset = 0
|
aoffset = 0
|
||||||
autosize = int32(textstksiz + 8)
|
autosize = int32(textstksiz + 8)
|
||||||
@ -421,10 +342,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
} else if autosize&4 != 0 {
|
} else if autosize&4 != 0 {
|
||||||
autosize += 4
|
autosize += 4
|
||||||
}
|
}
|
||||||
p.To.Offset = int64(uint64(p.To.Offset)&(0xffffffff<<32) | uint64(uint32(autosize-8)))
|
p.To.Offset = int64(autosize) - 8
|
||||||
|
|
||||||
if !(p.Reg&obj.NOSPLIT != 0) {
|
if !(p.From3.Offset&obj.NOSPLIT != 0) {
|
||||||
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.Reg&obj.NEEDCTXT != 0))) // emit split check
|
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0))) // emit split check
|
||||||
}
|
}
|
||||||
|
|
||||||
q = p
|
q = p
|
||||||
@ -432,17 +353,15 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
if autosize != 0 {
|
if autosize != 0 {
|
||||||
/* use MOVDU to adjust R1 when saving R31, if autosize is small */
|
/* use MOVDU to adjust R1 when saving R31, if autosize is small */
|
||||||
if !(cursym.Text.Mark&LEAF != 0) && autosize >= -BIG && autosize <= BIG {
|
if !(cursym.Text.Mark&LEAF != 0) && autosize >= -BIG && autosize <= BIG {
|
||||||
|
|
||||||
mov = AMOVDU
|
mov = AMOVDU
|
||||||
aoffset = int(-autosize)
|
aoffset = int(-autosize)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, p)
|
q = obj.Appendp(ctxt, p)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.From.Type = D_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
q.From.Offset = int64(-autosize)
|
q.From.Offset = int64(-autosize)
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REGSP
|
q.To.Reg = REGSP
|
||||||
q.Spadj = +autosize
|
q.Spadj = +autosize
|
||||||
}
|
}
|
||||||
@ -463,24 +382,24 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.From.Type = D_SPR
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Offset = D_LR
|
q.From.Reg = REG_LR
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REGTMP
|
q.To.Reg = REGTMP
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = int16(mov)
|
q.As = int16(mov)
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.From.Type = D_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = REGTMP
|
q.From.Reg = REGTMP
|
||||||
q.To.Type = D_OREG
|
q.To.Type = obj.TYPE_MEM
|
||||||
q.To.Offset = int64(aoffset)
|
q.To.Offset = int64(aoffset)
|
||||||
q.To.Reg = REGSP
|
q.To.Reg = REGSP
|
||||||
if q.As == AMOVDU {
|
if q.As == AMOVDU {
|
||||||
q.Spadj = int32(-aoffset)
|
q.Spadj = int32(-aoffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cursym.Text.Reg&obj.WRAPPER != 0 {
|
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||||
//
|
//
|
||||||
// MOVD g_panic(g), R3
|
// MOVD g_panic(g), R3
|
||||||
@ -501,109 +420,109 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
|
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = D_OREG
|
q.From.Type = obj.TYPE_MEM
|
||||||
q.From.Reg = REGG
|
q.From.Reg = REGG
|
||||||
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
|
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = 3
|
q.To.Reg = REG_R3
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = ACMP
|
q.As = ACMP
|
||||||
q.From.Type = D_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = 0
|
q.From.Reg = REG_R0
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = 3
|
q.To.Reg = REG_R3
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = ABEQ
|
q.As = ABEQ
|
||||||
q.To.Type = D_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
p1 = q
|
p1 = q
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = D_OREG
|
q.From.Type = obj.TYPE_MEM
|
||||||
q.From.Reg = 3
|
q.From.Reg = REG_R3
|
||||||
q.From.Offset = 0 // Panic.argp
|
q.From.Offset = 0 // Panic.argp
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = 4
|
q.To.Reg = REG_R4
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.From.Type = D_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
q.From.Offset = int64(autosize) + 8
|
q.From.Offset = int64(autosize) + 8
|
||||||
q.Reg = REGSP
|
q.Reg = REGSP
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = 5
|
q.To.Reg = REG_R5
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = ACMP
|
q.As = ACMP
|
||||||
q.From.Type = D_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = 4
|
q.From.Reg = REG_R4
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = 5
|
q.To.Reg = REG_R5
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = ABNE
|
q.As = ABNE
|
||||||
q.To.Type = D_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
p2 = q
|
p2 = q
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.From.Type = D_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
q.From.Offset = 8
|
q.From.Offset = 8
|
||||||
q.Reg = REGSP
|
q.Reg = REGSP
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = 6
|
q.To.Reg = REG_R6
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = D_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = 6
|
q.From.Reg = REG_R6
|
||||||
q.To.Type = D_OREG
|
q.To.Type = obj.TYPE_MEM
|
||||||
q.To.Reg = 3
|
q.To.Reg = REG_R3
|
||||||
q.To.Offset = 0 // Panic.argp
|
q.To.Offset = 0 // Panic.argp
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
|
|
||||||
q.As = ANOP
|
q.As = obj.ANOP
|
||||||
p1.Pcond = q
|
p1.Pcond = q
|
||||||
p2.Pcond = q
|
p2.Pcond = q
|
||||||
}
|
}
|
||||||
|
|
||||||
case ARETURN:
|
case ARETURN:
|
||||||
if p.From.Type == D_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
ctxt.Diag("using BECOME (%v) is not supported!", p)
|
ctxt.Diag("using BECOME (%v) is not supported!", p)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.To.Sym != nil { // retjmp
|
if p.To.Sym != nil { // retjmp
|
||||||
p.As = ABR
|
p.As = ABR
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if cursym.Text.Mark&LEAF != 0 {
|
if cursym.Text.Mark&LEAF != 0 {
|
||||||
if !(autosize != 0) {
|
if !(autosize != 0) {
|
||||||
p.As = ABR
|
p.As = ABR
|
||||||
p.From = zprg.From
|
p.From = obj.Zprog.From
|
||||||
p.To.Type = D_SPR
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Offset = D_LR
|
p.To.Reg = REG_LR
|
||||||
p.Mark |= BRANCH
|
p.Mark |= BRANCH
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(autosize)
|
p.From.Offset = int64(autosize)
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGSP
|
p.To.Reg = REGSP
|
||||||
p.Spadj = -autosize
|
p.Spadj = -autosize
|
||||||
|
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
q.As = ABR
|
q.As = ABR
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.To.Type = D_SPR
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Offset = D_LR
|
q.To.Reg = REG_LR
|
||||||
q.Mark |= BRANCH
|
q.Mark |= BRANCH
|
||||||
q.Spadj = +autosize
|
q.Spadj = +autosize
|
||||||
|
|
||||||
@ -613,19 +532,19 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Offset = 0
|
p.From.Offset = 0
|
||||||
p.From.Reg = REGSP
|
p.From.Reg = REGSP
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGTMP
|
p.To.Reg = REGTMP
|
||||||
|
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.From.Type = D_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = REGTMP
|
q.From.Reg = REGTMP
|
||||||
q.To.Type = D_SPR
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Offset = D_LR
|
q.To.Reg = REG_LR
|
||||||
|
|
||||||
q.Link = p.Link
|
q.Link = p.Link
|
||||||
p.Link = q
|
p.Link = q
|
||||||
@ -633,14 +552,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
if false {
|
if false {
|
||||||
// Debug bad returns
|
// Debug bad returns
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
|
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.From.Type = D_OREG
|
q.From.Type = obj.TYPE_MEM
|
||||||
q.From.Offset = 0
|
q.From.Offset = 0
|
||||||
q.From.Reg = REGTMP
|
q.From.Reg = REGTMP
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REGTMP
|
q.To.Reg = REGTMP
|
||||||
|
|
||||||
q.Link = p.Link
|
q.Link = p.Link
|
||||||
@ -649,12 +568,12 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if autosize != 0 {
|
if autosize != 0 {
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.From.Type = D_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
q.From.Offset = int64(autosize)
|
q.From.Offset = int64(autosize)
|
||||||
q.To.Type = D_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REGSP
|
q.To.Reg = REGSP
|
||||||
q.Spadj = -autosize
|
q.Spadj = -autosize
|
||||||
|
|
||||||
@ -662,11 +581,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
p.Link = q
|
p.Link = q
|
||||||
}
|
}
|
||||||
|
|
||||||
q1 = ctxt.NewProg()
|
q1 = new(obj.Prog)
|
||||||
q1.As = ABR
|
q1.As = ABR
|
||||||
q1.Lineno = p.Lineno
|
q1.Lineno = p.Lineno
|
||||||
q1.To.Type = D_SPR
|
q1.To.Type = obj.TYPE_REG
|
||||||
q1.To.Offset = D_LR
|
q1.To.Reg = REG_LR
|
||||||
q1.Mark |= BRANCH
|
q1.Mark |= BRANCH
|
||||||
q1.Spadj = +autosize
|
q1.Spadj = +autosize
|
||||||
|
|
||||||
@ -674,7 +593,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
q.Link = q1
|
q.Link = q1
|
||||||
|
|
||||||
case AADD:
|
case AADD:
|
||||||
if p.To.Type == D_REG && p.To.Reg == REGSP && p.From.Type == D_CONST {
|
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST {
|
||||||
p.Spadj = int32(-p.From.Offset)
|
p.Spadj = int32(-p.From.Offset)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -728,7 +647,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.Prog {
|
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.Prog {
|
||||||
|
|
||||||
var q *obj.Prog
|
var q *obj.Prog
|
||||||
var q1 *obj.Prog
|
var q1 *obj.Prog
|
||||||
|
|
||||||
@ -736,14 +654,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
p.From.Type = D_OREG
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Reg = REGG
|
p.From.Reg = REGG
|
||||||
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
|
||||||
if ctxt.Cursym.Cfunc != 0 {
|
if ctxt.Cursym.Cfunc != 0 {
|
||||||
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
|
||||||
}
|
}
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 3
|
p.To.Reg = REG_R3
|
||||||
|
|
||||||
q = nil
|
q = nil
|
||||||
if framesize <= obj.StackSmall {
|
if framesize <= obj.StackSmall {
|
||||||
@ -752,9 +670,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ACMPU
|
p.As = ACMPU
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 3
|
p.From.Reg = REG_R3
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGSP
|
p.To.Reg = REGSP
|
||||||
} else if framesize <= obj.StackBig {
|
} else if framesize <= obj.StackBig {
|
||||||
// large stack: SP-framesize < stackguard-StackSmall
|
// large stack: SP-framesize < stackguard-StackSmall
|
||||||
@ -763,20 +681,19 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(-framesize)
|
p.From.Offset = int64(-framesize)
|
||||||
p.Reg = REGSP
|
p.Reg = REGSP
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 4
|
p.To.Reg = REG_R4
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMPU
|
p.As = ACMPU
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 3
|
p.From.Reg = REG_R3
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 4
|
p.To.Reg = REG_R4
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Such a large stack we need to protect against wraparound.
|
// Such a large stack we need to protect against wraparound.
|
||||||
// If SP is close to zero:
|
// If SP is close to zero:
|
||||||
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
|
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
|
||||||
@ -795,44 +712,44 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 3
|
p.From.Reg = REG_R3
|
||||||
p.To.Type = D_CONST
|
p.To.Type = obj.TYPE_CONST
|
||||||
p.To.Offset = obj.StackPreempt
|
p.To.Offset = obj.StackPreempt
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
q = p
|
q = p
|
||||||
p.As = ABEQ
|
p.As = ABEQ
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = obj.StackGuard
|
p.From.Offset = obj.StackGuard
|
||||||
p.Reg = REGSP
|
p.Reg = REGSP
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 4
|
p.To.Reg = REG_R4
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ASUB
|
p.As = ASUB
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = 3
|
p.From.Reg = REG_R3
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 4
|
p.To.Reg = REG_R4
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
p.From.Type = D_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
|
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGTMP
|
p.To.Reg = REGTMP
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ACMPU
|
p.As = ACMPU
|
||||||
p.From.Type = D_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REGTMP
|
p.From.Reg = REGTMP
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 4
|
p.To.Reg = REG_R4
|
||||||
}
|
}
|
||||||
|
|
||||||
// q1: BLT done
|
// q1: BLT done
|
||||||
@ -840,16 +757,16 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
q1 = p
|
q1 = p
|
||||||
|
|
||||||
p.As = ABLT
|
p.As = ABLT
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
|
|
||||||
// MOVD LR, R5
|
// MOVD LR, R5
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
p.From.Type = D_SPR
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Offset = D_LR
|
p.From.Reg = REG_LR
|
||||||
p.To.Type = D_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = 5
|
p.To.Reg = REG_R5
|
||||||
if q != nil {
|
if q != nil {
|
||||||
q.Pcond = p
|
q.Pcond = p
|
||||||
}
|
}
|
||||||
@ -858,11 +775,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ABL
|
p.As = ABL
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
if ctxt.Cursym.Cfunc != 0 {
|
if ctxt.Cursym.Cfunc != 0 {
|
||||||
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
|
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
p.To.Sym = ctxt.Symmorestack[noctxt]
|
p.To.Sym = ctxt.Symmorestack[noctxt]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,13 +786,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
|
|||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ABR
|
p.As = ABR
|
||||||
p.To.Type = D_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.Pcond = ctxt.Cursym.Text.Link
|
p.Pcond = ctxt.Cursym.Text.Link
|
||||||
|
|
||||||
// placeholder for q1's jump target
|
// placeholder for q1's jump target
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
p.As = ANOP // zero-width place holder
|
p.As = obj.ANOP // zero-width place holder
|
||||||
q1.Pcond = p
|
q1.Pcond = p
|
||||||
|
|
||||||
return p
|
return p
|
||||||
@ -888,7 +804,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
|
|||||||
|
|
||||||
ctxt.Cursym = s
|
ctxt.Cursym = s
|
||||||
|
|
||||||
firstp = ctxt.NewProg()
|
firstp = new(obj.Prog)
|
||||||
lastp = firstp
|
lastp = firstp
|
||||||
xfol(ctxt, s.Text, &lastp)
|
xfol(ctxt, s.Text, &lastp)
|
||||||
lastp.Link = nil
|
lastp.Link = nil
|
||||||
@ -966,7 +882,7 @@ loop:
|
|||||||
}
|
}
|
||||||
b = 0 /* set */
|
b = 0 /* set */
|
||||||
a = int(q.As)
|
a = int(q.As)
|
||||||
if a == ANOP {
|
if a == obj.ANOP {
|
||||||
i--
|
i--
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -984,7 +900,7 @@ loop:
|
|||||||
|
|
||||||
copy:
|
copy:
|
||||||
for {
|
for {
|
||||||
r = ctxt.NewProg()
|
r = new(obj.Prog)
|
||||||
*r = *p
|
*r = *p
|
||||||
if !(r.Mark&FOLL != 0) {
|
if !(r.Mark&FOLL != 0) {
|
||||||
fmt.Printf("cant happen 1\n")
|
fmt.Printf("cant happen 1\n")
|
||||||
@ -1016,10 +932,10 @@ loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
a = ABR
|
a = ABR
|
||||||
q = ctxt.NewProg()
|
q = new(obj.Prog)
|
||||||
q.As = int16(a)
|
q.As = int16(a)
|
||||||
q.Lineno = p.Lineno
|
q.Lineno = p.Lineno
|
||||||
q.To.Type = D_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q.To.Offset = p.Pc
|
q.To.Offset = p.Pc
|
||||||
q.Pcond = p
|
q.Pcond = p
|
||||||
p = q
|
p = q
|
||||||
@ -1052,97 +968,32 @@ loop:
|
|||||||
goto loop
|
goto loop
|
||||||
}
|
}
|
||||||
|
|
||||||
func prg() *obj.Prog {
|
|
||||||
p := zprg
|
|
||||||
return &p
|
|
||||||
}
|
|
||||||
|
|
||||||
var Linkppc64 = obj.LinkArch{
|
var Linkppc64 = obj.LinkArch{
|
||||||
ByteOrder: binary.BigEndian,
|
ByteOrder: binary.BigEndian,
|
||||||
Pconv: Pconv,
|
Pconv: Pconv,
|
||||||
Name: "ppc64",
|
Name: "ppc64",
|
||||||
Thechar: '9',
|
Thechar: '9',
|
||||||
Endian: obj.BigEndian,
|
Endian: obj.BigEndian,
|
||||||
Addstacksplit: addstacksplit,
|
Preprocess: preprocess,
|
||||||
Assemble: span9,
|
Assemble: span9,
|
||||||
Datasize: datasize,
|
Follow: follow,
|
||||||
Follow: follow,
|
Progedit: progedit,
|
||||||
Iscall: iscall,
|
Minlc: 4,
|
||||||
Isdata: isdata,
|
Ptrsize: 8,
|
||||||
Prg: prg,
|
Regsize: 8,
|
||||||
Progedit: progedit,
|
|
||||||
Settextflag: settextflag,
|
|
||||||
Symtype: symtype,
|
|
||||||
Textflag: textflag,
|
|
||||||
Minlc: 4,
|
|
||||||
Ptrsize: 8,
|
|
||||||
Regsize: 8,
|
|
||||||
D_ADDR: D_ADDR,
|
|
||||||
D_AUTO: D_AUTO,
|
|
||||||
D_BRANCH: D_BRANCH,
|
|
||||||
D_CONST: D_CONST,
|
|
||||||
D_EXTERN: D_EXTERN,
|
|
||||||
D_FCONST: D_FCONST,
|
|
||||||
D_NONE: D_NONE,
|
|
||||||
D_PARAM: D_PARAM,
|
|
||||||
D_SCONST: D_SCONST,
|
|
||||||
D_STATIC: D_STATIC,
|
|
||||||
D_OREG: D_OREG,
|
|
||||||
ACALL: ABL,
|
|
||||||
ADATA: ADATA,
|
|
||||||
AEND: AEND,
|
|
||||||
AFUNCDATA: AFUNCDATA,
|
|
||||||
AGLOBL: AGLOBL,
|
|
||||||
AJMP: ABR,
|
|
||||||
ANOP: ANOP,
|
|
||||||
APCDATA: APCDATA,
|
|
||||||
ARET: ARETURN,
|
|
||||||
ATEXT: ATEXT,
|
|
||||||
ATYPE: ATYPE,
|
|
||||||
AUSEFIELD: AUSEFIELD,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var Linkppc64le = obj.LinkArch{
|
var Linkppc64le = obj.LinkArch{
|
||||||
ByteOrder: binary.LittleEndian,
|
ByteOrder: binary.LittleEndian,
|
||||||
Pconv: Pconv,
|
Pconv: Pconv,
|
||||||
Name: "ppc64le",
|
Name: "ppc64le",
|
||||||
Thechar: '9',
|
Thechar: '9',
|
||||||
Endian: obj.LittleEndian,
|
Endian: obj.LittleEndian,
|
||||||
Addstacksplit: addstacksplit,
|
Preprocess: preprocess,
|
||||||
Assemble: span9,
|
Assemble: span9,
|
||||||
Datasize: datasize,
|
Follow: follow,
|
||||||
Follow: follow,
|
Progedit: progedit,
|
||||||
Iscall: iscall,
|
Minlc: 4,
|
||||||
Isdata: isdata,
|
Ptrsize: 8,
|
||||||
Prg: prg,
|
Regsize: 8,
|
||||||
Progedit: progedit,
|
|
||||||
Settextflag: settextflag,
|
|
||||||
Symtype: symtype,
|
|
||||||
Textflag: textflag,
|
|
||||||
Minlc: 4,
|
|
||||||
Ptrsize: 8,
|
|
||||||
Regsize: 8,
|
|
||||||
D_ADDR: D_ADDR,
|
|
||||||
D_AUTO: D_AUTO,
|
|
||||||
D_BRANCH: D_BRANCH,
|
|
||||||
D_CONST: D_CONST,
|
|
||||||
D_EXTERN: D_EXTERN,
|
|
||||||
D_FCONST: D_FCONST,
|
|
||||||
D_NONE: D_NONE,
|
|
||||||
D_PARAM: D_PARAM,
|
|
||||||
D_SCONST: D_SCONST,
|
|
||||||
D_STATIC: D_STATIC,
|
|
||||||
D_OREG: D_OREG,
|
|
||||||
ACALL: ABL,
|
|
||||||
ADATA: ADATA,
|
|
||||||
AEND: AEND,
|
|
||||||
AFUNCDATA: AFUNCDATA,
|
|
||||||
AGLOBL: AGLOBL,
|
|
||||||
AJMP: ABR,
|
|
||||||
ANOP: ANOP,
|
|
||||||
APCDATA: APCDATA,
|
|
||||||
ARET: ARETURN,
|
|
||||||
ATEXT: ATEXT,
|
|
||||||
ATYPE: ATYPE,
|
|
||||||
AUSEFIELD: AUSEFIELD,
|
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,6 @@ var headers = []struct {
|
|||||||
name string
|
name string
|
||||||
val int
|
val int
|
||||||
}{
|
}{
|
||||||
struct {
|
|
||||||
name string
|
|
||||||
val int
|
|
||||||
}{"android", Hlinux},
|
|
||||||
struct {
|
struct {
|
||||||
name string
|
name string
|
||||||
val int
|
val int
|
||||||
@ -70,6 +66,10 @@ var headers = []struct {
|
|||||||
name string
|
name string
|
||||||
val int
|
val int
|
||||||
}{"linux", Hlinux},
|
}{"linux", Hlinux},
|
||||||
|
struct {
|
||||||
|
name string
|
||||||
|
val int
|
||||||
|
}{"android", Hlinux}, // must be after "linux" entry or else headstr(Hlinux) == "android"
|
||||||
struct {
|
struct {
|
||||||
name string
|
name string
|
||||||
val int
|
val int
|
||||||
@ -129,6 +129,8 @@ func Linknew(arch *LinkArch) *Link {
|
|||||||
var p string
|
var p string
|
||||||
var buf string
|
var buf string
|
||||||
|
|
||||||
|
linksetexp()
|
||||||
|
|
||||||
ctxt = new(Link)
|
ctxt = new(Link)
|
||||||
ctxt.Arch = arch
|
ctxt.Arch = arch
|
||||||
ctxt.Version = HistVersion
|
ctxt.Version = HistVersion
|
||||||
@ -151,7 +153,6 @@ func Linknew(arch *LinkArch) *Link {
|
|||||||
// Record thread-local storage offset.
|
// Record thread-local storage offset.
|
||||||
// TODO(rsc): Move tlsoffset back into the linker.
|
// TODO(rsc): Move tlsoffset back into the linker.
|
||||||
switch ctxt.Headtype {
|
switch ctxt.Headtype {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype))
|
log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype))
|
||||||
|
|
||||||
@ -194,7 +195,6 @@ func Linknew(arch *LinkArch) *Link {
|
|||||||
*/
|
*/
|
||||||
case Hdarwin:
|
case Hdarwin:
|
||||||
switch ctxt.Arch.Thechar {
|
switch ctxt.Arch.Thechar {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name)
|
log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name)
|
||||||
|
|
||||||
@ -211,12 +211,10 @@ func Linknew(arch *LinkArch) *Link {
|
|||||||
|
|
||||||
// On arm, record goarm.
|
// On arm, record goarm.
|
||||||
if ctxt.Arch.Thechar == '5' {
|
if ctxt.Arch.Thechar == '5' {
|
||||||
|
|
||||||
p = Getgoarm()
|
p = Getgoarm()
|
||||||
if p != "" {
|
if p != "" {
|
||||||
ctxt.Goarm = int32(Atoi(p))
|
ctxt.Goarm = int32(Atoi(p))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ctxt.Goarm = 6
|
ctxt.Goarm = 6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,6 +279,5 @@ func Linklookup(ctxt *Link, name string, v int) *LSym {
|
|||||||
|
|
||||||
// read-only lookup
|
// read-only lookup
|
||||||
func linkrlookup(ctxt *Link, name string, v int) *LSym {
|
func linkrlookup(ctxt *Link, name string, v int) *LSym {
|
||||||
|
|
||||||
return _lookup(ctxt, name, v, 0)
|
return _lookup(ctxt, name, v, 0)
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,19 @@ func Cputime() float64 {
|
|||||||
type Biobuf struct {
|
type Biobuf struct {
|
||||||
unget int
|
unget int
|
||||||
haveUnget bool
|
haveUnget bool
|
||||||
|
f *os.File
|
||||||
r *bufio.Reader
|
r *bufio.Reader
|
||||||
w *bufio.Writer
|
w *bufio.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Bopenw(name string) (*Biobuf, error) {
|
||||||
|
f, err := os.Open(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Biobuf{f: f, w: bufio.NewWriter(f)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func Binitw(w io.Writer) *Biobuf {
|
func Binitw(w io.Writer) *Biobuf {
|
||||||
return &Biobuf{w: bufio.NewWriter(w)}
|
return &Biobuf{w: bufio.NewWriter(w)}
|
||||||
}
|
}
|
||||||
@ -75,6 +84,15 @@ func Bflush(b *Biobuf) error {
|
|||||||
return b.w.Flush()
|
return b.w.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Bterm(b *Biobuf) error {
|
||||||
|
err := b.w.Flush()
|
||||||
|
err1 := b.f.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func envOr(key, value string) string {
|
func envOr(key, value string) string {
|
||||||
if x := os.Getenv(key); x != "" {
|
if x := os.Getenv(key); x != "" {
|
||||||
return x
|
return x
|
||||||
@ -108,7 +126,7 @@ func Atoi(s string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Prog) Line() string {
|
func (p *Prog) Line() string {
|
||||||
return linklinefmt(p.Ctxt, int(p.Lineno), false, false)
|
return Linklinefmt(p.Ctxt, int(p.Lineno), false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Prog) String() string {
|
func (p *Prog) String() string {
|
||||||
@ -119,7 +137,11 @@ func (p *Prog) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctxt *Link) NewProg() *Prog {
|
func (ctxt *Link) NewProg() *Prog {
|
||||||
p := ctxt.Arch.Prg() // should be the only call to this; all others should use ctxt.NewProg
|
p := new(Prog) // should be the only call to this; all others should use ctxt.NewProg
|
||||||
p.Ctxt = ctxt
|
p.Ctxt = ctxt
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctxt *Link) Line(n int) string {
|
||||||
|
return Linklinefmt(ctxt, n, false, false)
|
||||||
|
}
|
||||||
|
@ -30,12 +30,13 @@
|
|||||||
|
|
||||||
package x86
|
package x86
|
||||||
|
|
||||||
|
import "cmd/internal/obj"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* amd64
|
* amd64
|
||||||
*/
|
*/
|
||||||
const (
|
const (
|
||||||
AXXX = iota
|
AAAA = obj.A_ARCHSPECIFIC + iota
|
||||||
AAAA
|
|
||||||
AAAD
|
AAAD
|
||||||
AAAM
|
AAAM
|
||||||
AAAS
|
AAAS
|
||||||
@ -65,7 +66,6 @@ const (
|
|||||||
ABTSL
|
ABTSL
|
||||||
ABTSW
|
ABTSW
|
||||||
ABYTE
|
ABYTE
|
||||||
ACALL
|
|
||||||
ACLC
|
ACLC
|
||||||
ACLD
|
ACLD
|
||||||
ACLI
|
ACLI
|
||||||
@ -79,7 +79,6 @@ const (
|
|||||||
ACMPSW
|
ACMPSW
|
||||||
ADAA
|
ADAA
|
||||||
ADAS
|
ADAS
|
||||||
ADATA
|
|
||||||
ADECB
|
ADECB
|
||||||
ADECL
|
ADECL
|
||||||
ADECQ
|
ADECQ
|
||||||
@ -88,9 +87,6 @@ const (
|
|||||||
ADIVL
|
ADIVL
|
||||||
ADIVW
|
ADIVW
|
||||||
AENTER
|
AENTER
|
||||||
AGLOBL
|
|
||||||
AGOK
|
|
||||||
AHISTORY
|
|
||||||
AHLT
|
AHLT
|
||||||
AIDIVB
|
AIDIVB
|
||||||
AIDIVL
|
AIDIVL
|
||||||
@ -123,7 +119,6 @@ const (
|
|||||||
AJLS
|
AJLS
|
||||||
AJLT
|
AJLT
|
||||||
AJMI
|
AJMI
|
||||||
AJMP
|
|
||||||
AJNE
|
AJNE
|
||||||
AJOC
|
AJOC
|
||||||
AJOS
|
AJOS
|
||||||
@ -166,11 +161,9 @@ const (
|
|||||||
AMULB
|
AMULB
|
||||||
AMULL
|
AMULL
|
||||||
AMULW
|
AMULW
|
||||||
ANAME
|
|
||||||
ANEGB
|
ANEGB
|
||||||
ANEGL
|
ANEGL
|
||||||
ANEGW
|
ANEGW
|
||||||
ANOP
|
|
||||||
ANOTB
|
ANOTB
|
||||||
ANOTL
|
ANOTL
|
||||||
ANOTW
|
ANOTW
|
||||||
@ -204,7 +197,6 @@ const (
|
|||||||
ARCRW
|
ARCRW
|
||||||
AREP
|
AREP
|
||||||
AREPN
|
AREPN
|
||||||
ARET
|
|
||||||
AROLB
|
AROLB
|
||||||
AROLL
|
AROLL
|
||||||
AROLW
|
AROLW
|
||||||
@ -261,7 +253,6 @@ const (
|
|||||||
ATESTB
|
ATESTB
|
||||||
ATESTL
|
ATESTL
|
||||||
ATESTW
|
ATESTW
|
||||||
ATEXT
|
|
||||||
AVERR
|
AVERR
|
||||||
AVERW
|
AVERW
|
||||||
AWAIT
|
AWAIT
|
||||||
@ -370,10 +361,6 @@ const (
|
|||||||
AFXTRACT
|
AFXTRACT
|
||||||
AFYL2X
|
AFYL2X
|
||||||
AFYL2XP1
|
AFYL2XP1
|
||||||
AEND
|
|
||||||
ADYNT_
|
|
||||||
AINIT_
|
|
||||||
ASIGNAME
|
|
||||||
ACMPXCHGB
|
ACMPXCHGB
|
||||||
ACMPXCHGL
|
ACMPXCHGL
|
||||||
ACMPXCHGW
|
ACMPXCHGW
|
||||||
@ -714,7 +701,6 @@ const (
|
|||||||
AMOVQL
|
AMOVQL
|
||||||
ABSWAPL
|
ABSWAPL
|
||||||
ABSWAPQ
|
ABSWAPQ
|
||||||
AUNDEF
|
|
||||||
AAESENC
|
AAESENC
|
||||||
AAESENCLAST
|
AAESENCLAST
|
||||||
AAESDEC
|
AAESDEC
|
||||||
@ -723,100 +709,89 @@ const (
|
|||||||
AAESKEYGENASSIST
|
AAESKEYGENASSIST
|
||||||
APSHUFD
|
APSHUFD
|
||||||
APCLMULQDQ
|
APCLMULQDQ
|
||||||
AUSEFIELD
|
|
||||||
ATYPE
|
|
||||||
AFUNCDATA
|
|
||||||
APCDATA
|
|
||||||
ACHECKNIL
|
|
||||||
AVARDEF
|
|
||||||
AVARKILL
|
|
||||||
ADUFFCOPY
|
|
||||||
ADUFFZERO
|
|
||||||
ALAST
|
ALAST
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
D_AL = 0 + iota
|
REG_NONE = 0
|
||||||
D_CL
|
REG_AL = 0 + 16 + iota - 1
|
||||||
D_DL
|
REG_CL
|
||||||
D_BL
|
REG_DL
|
||||||
D_SPB
|
REG_BL
|
||||||
D_BPB
|
REG_SPB
|
||||||
D_SIB
|
REG_BPB
|
||||||
D_DIB
|
REG_SIB
|
||||||
D_R8B
|
REG_DIB
|
||||||
D_R9B
|
REG_R8B
|
||||||
D_R10B
|
REG_R9B
|
||||||
D_R11B
|
REG_R10B
|
||||||
D_R12B
|
REG_R11B
|
||||||
D_R13B
|
REG_R12B
|
||||||
D_R14B
|
REG_R13B
|
||||||
D_R15B
|
REG_R14B
|
||||||
D_AX = 16 + iota - 16
|
REG_R15B
|
||||||
D_CX
|
REG_AX = 16 + 16 + iota - 17
|
||||||
D_DX
|
REG_CX
|
||||||
D_BX
|
REG_DX
|
||||||
D_SP
|
REG_BX
|
||||||
D_BP
|
REG_SP
|
||||||
D_SI
|
REG_BP
|
||||||
D_DI
|
REG_SI
|
||||||
D_R8
|
REG_DI
|
||||||
D_R9
|
REG_R8
|
||||||
D_R10
|
REG_R9
|
||||||
D_R11
|
REG_R10
|
||||||
D_R12
|
REG_R11
|
||||||
D_R13
|
REG_R12
|
||||||
D_R14
|
REG_R13
|
||||||
D_R15
|
REG_R14
|
||||||
D_AH = 32 + iota - 32
|
REG_R15
|
||||||
D_CH
|
REG_AH = 32 + 16 + iota - 33
|
||||||
D_DH
|
REG_CH
|
||||||
D_BH
|
REG_DH
|
||||||
D_F0 = 36
|
REG_BH
|
||||||
D_M0 = 44
|
REG_F0 = 36 + 16
|
||||||
D_X0 = 52 + iota - 38
|
REG_M0 = 44 + 16
|
||||||
D_X1
|
REG_X0 = 52 + 16 + iota - 39
|
||||||
D_X2
|
REG_X1
|
||||||
D_X3
|
REG_X2
|
||||||
D_X4
|
REG_X3
|
||||||
D_X5
|
REG_X4
|
||||||
D_X6
|
REG_X5
|
||||||
D_X7
|
REG_X6
|
||||||
D_X8
|
REG_X7
|
||||||
D_X9
|
REG_X8
|
||||||
D_X10
|
REG_X9
|
||||||
D_X11
|
REG_X10
|
||||||
D_X12
|
REG_X11
|
||||||
D_X13
|
REG_X12
|
||||||
D_X14
|
REG_X13
|
||||||
D_X15
|
REG_X14
|
||||||
D_CS = 68 + iota - 54
|
REG_X15
|
||||||
D_SS
|
REG_CS = 68 + 16 + iota - 55
|
||||||
D_DS
|
REG_SS
|
||||||
D_ES
|
REG_DS
|
||||||
D_FS
|
REG_ES
|
||||||
D_GS
|
REG_FS
|
||||||
D_GDTR
|
REG_GS
|
||||||
D_IDTR
|
REG_GDTR
|
||||||
D_LDTR
|
REG_IDTR
|
||||||
D_MSW
|
REG_LDTR
|
||||||
D_TASK
|
REG_MSW
|
||||||
D_CR = 79
|
REG_TASK
|
||||||
D_DR = 95
|
REG_CR = 79 + 16
|
||||||
D_TR = 103
|
REG_DR = 95 + 16
|
||||||
D_TLS = 111
|
REG_TR = 103 + 16
|
||||||
D_NONE = 112
|
REG_TLS = 111 + 16 + iota - 69
|
||||||
D_BRANCH = 113
|
MAXREG
|
||||||
D_EXTERN = 114
|
REGARG = -1
|
||||||
D_STATIC = 115
|
REGRET = REG_AX
|
||||||
D_AUTO = 116
|
FREGRET = REG_X0
|
||||||
D_PARAM = 117
|
REGSP = REG_SP
|
||||||
D_CONST = 118
|
REGTMP = REG_DI
|
||||||
D_FCONST = 119
|
REGEXT = REG_R15
|
||||||
D_SCONST = 120
|
FREGMIN = REG_X0 + 5
|
||||||
D_ADDR = 121 + iota - 78
|
FREGEXT = REG_X0 + 15
|
||||||
D_INDIR
|
|
||||||
D_LAST
|
|
||||||
T_TYPE = 1 << 0
|
T_TYPE = 1 << 0
|
||||||
T_INDEX = 1 << 1
|
T_INDEX = 1 << 1
|
||||||
T_OFFSET = 1 << 2
|
T_OFFSET = 1 << 2
|
||||||
@ -825,12 +800,4 @@ const (
|
|||||||
T_SCONST = 1 << 5
|
T_SCONST = 1 << 5
|
||||||
T_64 = 1 << 6
|
T_64 = 1 << 6
|
||||||
T_GOTYPE = 1 << 7
|
T_GOTYPE = 1 << 7
|
||||||
REGARG = -1
|
|
||||||
REGRET = D_AX
|
|
||||||
FREGRET = D_X0
|
|
||||||
REGSP = D_SP
|
|
||||||
REGTMP = D_DI
|
|
||||||
REGEXT = D_R15
|
|
||||||
FREGMIN = D_X0 + 5
|
|
||||||
FREGEXT = D_X0 + 15
|
|
||||||
)
|
)
|
||||||
|
@ -4,8 +4,26 @@ package x86
|
|||||||
* this is the ranlib header
|
* this is the ranlib header
|
||||||
*/
|
*/
|
||||||
var Anames = []string{
|
var Anames = []string{
|
||||||
"XXX",
|
"XXX ",
|
||||||
"AAA",
|
"CALL",
|
||||||
|
"CHECKNIL",
|
||||||
|
"DATA",
|
||||||
|
"DUFFCOPY",
|
||||||
|
"DUFFZERO",
|
||||||
|
"END",
|
||||||
|
"FUNCDATA",
|
||||||
|
"GLOBL",
|
||||||
|
"JMP",
|
||||||
|
"NOP",
|
||||||
|
"PCDATA",
|
||||||
|
"RET",
|
||||||
|
"TEXT",
|
||||||
|
"TYPE",
|
||||||
|
"UNDEF",
|
||||||
|
"USEFIELD",
|
||||||
|
"VARDEF",
|
||||||
|
"VARKILL",
|
||||||
|
"AAA ",
|
||||||
"AAD",
|
"AAD",
|
||||||
"AAM",
|
"AAM",
|
||||||
"AAS",
|
"AAS",
|
||||||
@ -35,7 +53,6 @@ var Anames = []string{
|
|||||||
"BTSL",
|
"BTSL",
|
||||||
"BTSW",
|
"BTSW",
|
||||||
"BYTE",
|
"BYTE",
|
||||||
"CALL",
|
|
||||||
"CLC",
|
"CLC",
|
||||||
"CLD",
|
"CLD",
|
||||||
"CLI",
|
"CLI",
|
||||||
@ -49,7 +66,6 @@ var Anames = []string{
|
|||||||
"CMPSW",
|
"CMPSW",
|
||||||
"DAA",
|
"DAA",
|
||||||
"DAS",
|
"DAS",
|
||||||
"DATA",
|
|
||||||
"DECB",
|
"DECB",
|
||||||
"DECL",
|
"DECL",
|
||||||
"DECQ",
|
"DECQ",
|
||||||
@ -58,9 +74,6 @@ var Anames = []string{
|
|||||||
"DIVL",
|
"DIVL",
|
||||||
"DIVW",
|
"DIVW",
|
||||||
"ENTER",
|
"ENTER",
|
||||||
"GLOBL",
|
|
||||||
"GOK",
|
|
||||||
"HISTORY",
|
|
||||||
"HLT",
|
"HLT",
|
||||||
"IDIVB",
|
"IDIVB",
|
||||||
"IDIVL",
|
"IDIVL",
|
||||||
@ -93,7 +106,6 @@ var Anames = []string{
|
|||||||
"JLS",
|
"JLS",
|
||||||
"JLT",
|
"JLT",
|
||||||
"JMI",
|
"JMI",
|
||||||
"JMP",
|
|
||||||
"JNE",
|
"JNE",
|
||||||
"JOC",
|
"JOC",
|
||||||
"JOS",
|
"JOS",
|
||||||
@ -136,11 +148,9 @@ var Anames = []string{
|
|||||||
"MULB",
|
"MULB",
|
||||||
"MULL",
|
"MULL",
|
||||||
"MULW",
|
"MULW",
|
||||||
"NAME",
|
|
||||||
"NEGB",
|
"NEGB",
|
||||||
"NEGL",
|
"NEGL",
|
||||||
"NEGW",
|
"NEGW",
|
||||||
"NOP",
|
|
||||||
"NOTB",
|
"NOTB",
|
||||||
"NOTL",
|
"NOTL",
|
||||||
"NOTW",
|
"NOTW",
|
||||||
@ -174,7 +184,6 @@ var Anames = []string{
|
|||||||
"RCRW",
|
"RCRW",
|
||||||
"REP",
|
"REP",
|
||||||
"REPN",
|
"REPN",
|
||||||
"RET",
|
|
||||||
"ROLB",
|
"ROLB",
|
||||||
"ROLL",
|
"ROLL",
|
||||||
"ROLW",
|
"ROLW",
|
||||||
@ -231,7 +240,6 @@ var Anames = []string{
|
|||||||
"TESTB",
|
"TESTB",
|
||||||
"TESTL",
|
"TESTL",
|
||||||
"TESTW",
|
"TESTW",
|
||||||
"TEXT",
|
|
||||||
"VERR",
|
"VERR",
|
||||||
"VERW",
|
"VERW",
|
||||||
"WAIT",
|
"WAIT",
|
||||||
@ -340,10 +348,6 @@ var Anames = []string{
|
|||||||
"FXTRACT",
|
"FXTRACT",
|
||||||
"FYL2X",
|
"FYL2X",
|
||||||
"FYL2XP1",
|
"FYL2XP1",
|
||||||
"END",
|
|
||||||
"DYNT_",
|
|
||||||
"INIT_",
|
|
||||||
"SIGNAME",
|
|
||||||
"CMPXCHGB",
|
"CMPXCHGB",
|
||||||
"CMPXCHGL",
|
"CMPXCHGL",
|
||||||
"CMPXCHGW",
|
"CMPXCHGW",
|
||||||
@ -684,7 +688,6 @@ var Anames = []string{
|
|||||||
"MOVQL",
|
"MOVQL",
|
||||||
"BSWAPL",
|
"BSWAPL",
|
||||||
"BSWAPQ",
|
"BSWAPQ",
|
||||||
"UNDEF",
|
|
||||||
"AESENC",
|
"AESENC",
|
||||||
"AESENCLAST",
|
"AESENCLAST",
|
||||||
"AESDEC",
|
"AESDEC",
|
||||||
@ -693,97 +696,5 @@ var Anames = []string{
|
|||||||
"AESKEYGENASSIST",
|
"AESKEYGENASSIST",
|
||||||
"PSHUFD",
|
"PSHUFD",
|
||||||
"PCLMULQDQ",
|
"PCLMULQDQ",
|
||||||
"USEFIELD",
|
|
||||||
"TYPE",
|
|
||||||
"FUNCDATA",
|
|
||||||
"PCDATA",
|
|
||||||
"CHECKNIL",
|
|
||||||
"VARDEF",
|
|
||||||
"VARKILL",
|
|
||||||
"DUFFCOPY",
|
|
||||||
"DUFFZERO",
|
|
||||||
"LAST",
|
"LAST",
|
||||||
}
|
}
|
||||||
|
|
||||||
var dnames6 = []string{
|
|
||||||
D_AL: "AL",
|
|
||||||
D_CL: "CL",
|
|
||||||
D_DL: "DL",
|
|
||||||
D_BL: "BL",
|
|
||||||
D_SPB: "SPB",
|
|
||||||
D_BPB: "BPB",
|
|
||||||
D_SIB: "SIB",
|
|
||||||
D_DIB: "DIB",
|
|
||||||
D_R8B: "R8B",
|
|
||||||
D_R9B: "R9B",
|
|
||||||
D_R10B: "R10B",
|
|
||||||
D_R11B: "R11B",
|
|
||||||
D_R12B: "R12B",
|
|
||||||
D_R13B: "R13B",
|
|
||||||
D_R14B: "R14B",
|
|
||||||
D_R15B: "R15B",
|
|
||||||
D_AX: "AX",
|
|
||||||
D_CX: "CX",
|
|
||||||
D_DX: "DX",
|
|
||||||
D_BX: "BX",
|
|
||||||
D_SP: "SP",
|
|
||||||
D_BP: "BP",
|
|
||||||
D_SI: "SI",
|
|
||||||
D_DI: "DI",
|
|
||||||
D_R8: "R8",
|
|
||||||
D_R9: "R9",
|
|
||||||
D_R10: "R10",
|
|
||||||
D_R11: "R11",
|
|
||||||
D_R12: "R12",
|
|
||||||
D_R13: "R13",
|
|
||||||
D_R14: "R14",
|
|
||||||
D_R15: "R15",
|
|
||||||
D_AH: "AH",
|
|
||||||
D_CH: "CH",
|
|
||||||
D_DH: "DH",
|
|
||||||
D_BH: "BH",
|
|
||||||
D_F0: "F0",
|
|
||||||
D_M0: "M0",
|
|
||||||
D_X0: "X0",
|
|
||||||
D_X1: "X1",
|
|
||||||
D_X2: "X2",
|
|
||||||
D_X3: "X3",
|
|
||||||
D_X4: "X4",
|
|
||||||
D_X5: "X5",
|
|
||||||
D_X6: "X6",
|
|
||||||
D_X7: "X7",
|
|
||||||
D_X8: "X8",
|
|
||||||
D_X9: "X9",
|
|
||||||
D_X10: "X10",
|
|
||||||
D_X11: "X11",
|
|
||||||
D_X12: "X12",
|
|
||||||
D_X13: "X13",
|
|
||||||
D_X14: "X14",
|
|
||||||
D_X15: "X15",
|
|
||||||
D_CS: "CS",
|
|
||||||
D_SS: "SS",
|
|
||||||
D_DS: "DS",
|
|
||||||
D_ES: "ES",
|
|
||||||
D_FS: "FS",
|
|
||||||
D_GS: "GS",
|
|
||||||
D_GDTR: "GDTR",
|
|
||||||
D_IDTR: "IDTR",
|
|
||||||
D_LDTR: "LDTR",
|
|
||||||
D_MSW: "MSW",
|
|
||||||
D_TASK: "TASK",
|
|
||||||
D_CR: "CR",
|
|
||||||
D_DR: "DR",
|
|
||||||
D_TR: "TR",
|
|
||||||
D_TLS: "TLS",
|
|
||||||
D_NONE: "NONE",
|
|
||||||
D_BRANCH: "BRANCH",
|
|
||||||
D_EXTERN: "EXTERN",
|
|
||||||
D_STATIC: "STATIC",
|
|
||||||
D_AUTO: "AUTO",
|
|
||||||
D_PARAM: "PARAM",
|
|
||||||
D_CONST: "CONST",
|
|
||||||
D_FCONST: "FCONST",
|
|
||||||
D_SCONST: "SCONST",
|
|
||||||
D_ADDR: "ADDR",
|
|
||||||
D_INDIR: "INDIR",
|
|
||||||
}
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -40,7 +40,6 @@ import (
|
|||||||
// %A int Opcodes (instruction mnemonics)
|
// %A int Opcodes (instruction mnemonics)
|
||||||
//
|
//
|
||||||
// %D Addr* Addresses (instruction operands)
|
// %D Addr* Addresses (instruction operands)
|
||||||
// Flags: "%lD": seperate the high and low words of a constant by "-"
|
|
||||||
//
|
//
|
||||||
// %P Prog* Instructions
|
// %P Prog* Instructions
|
||||||
//
|
//
|
||||||
@ -59,16 +58,16 @@ func Pconv(p *obj.Prog) string {
|
|||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ADATA:
|
case obj.ADATA:
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
|
||||||
|
|
||||||
case ATEXT:
|
case obj.ATEXT:
|
||||||
if p.From.Scale != 0 {
|
if p.From3.Offset != 0 {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, fmtLong, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
||||||
|
|
||||||
default:
|
default:
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
|
||||||
@ -91,45 +90,26 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
|
|||||||
var s string
|
var s string
|
||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
var i int
|
switch a.Type {
|
||||||
|
|
||||||
i = int(a.Type)
|
|
||||||
|
|
||||||
if flag&fmtLong != 0 /*untyped*/ {
|
|
||||||
if i == D_CONST {
|
|
||||||
str = fmt.Sprintf("$%d-%d", a.Offset&0xffffffff, a.Offset>>32)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// ATEXT dst is not constant
|
|
||||||
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
|
|
||||||
}
|
|
||||||
|
|
||||||
goto brk
|
|
||||||
}
|
|
||||||
|
|
||||||
if i >= D_INDIR {
|
|
||||||
if a.Offset != 0 {
|
|
||||||
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR))
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR))
|
|
||||||
}
|
|
||||||
goto brk
|
|
||||||
}
|
|
||||||
|
|
||||||
switch i {
|
|
||||||
default:
|
default:
|
||||||
if a.Offset != 0 {
|
str = fmt.Sprintf("type=%d", a.Type)
|
||||||
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("%v", Rconv(i))
|
case obj.TYPE_NONE:
|
||||||
}
|
|
||||||
|
|
||||||
case D_NONE:
|
|
||||||
str = ""
|
str = ""
|
||||||
|
|
||||||
case D_BRANCH:
|
// TODO(rsc): This special case is for instructions like
|
||||||
|
// PINSRQ CX,$1,X6
|
||||||
|
// where the $1 is included in the p->to Addr.
|
||||||
|
// Move into a new field.
|
||||||
|
case obj.TYPE_REG:
|
||||||
|
if a.Offset != 0 {
|
||||||
|
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg)))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
|
||||||
|
|
||||||
|
case obj.TYPE_BRANCH:
|
||||||
if a.Sym != nil {
|
if a.Sym != nil {
|
||||||
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
|
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
|
||||||
} else if p != nil && p.Pcond != nil {
|
} else if p != nil && p.Pcond != nil {
|
||||||
@ -137,57 +117,79 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
|
|||||||
} else if a.U.Branch != nil {
|
} else if a.U.Branch != nil {
|
||||||
str = fmt.Sprintf("%d", a.U.Branch.Pc)
|
str = fmt.Sprintf("%d", a.U.Branch.Pc)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
str = fmt.Sprintf("%d(PC)", a.Offset)
|
str = fmt.Sprintf("%d(PC)", a.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_EXTERN:
|
case obj.TYPE_MEM:
|
||||||
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
|
switch a.Name {
|
||||||
|
default:
|
||||||
|
str = fmt.Sprintf("name=%d", a.Name)
|
||||||
|
|
||||||
case D_STATIC:
|
case obj.NAME_NONE:
|
||||||
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
|
if a.Offset != 0 {
|
||||||
|
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg)))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
|
||||||
|
}
|
||||||
|
|
||||||
case D_AUTO:
|
case obj.NAME_EXTERN:
|
||||||
if a.Sym != nil {
|
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
|
||||||
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("%d(SP)", a.Offset)
|
case obj.NAME_STATIC:
|
||||||
|
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
|
||||||
|
|
||||||
|
case obj.NAME_AUTO:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%d(SP)", a.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
case obj.NAME_PARAM:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%d(FP)", a.Offset)
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_PARAM:
|
if a.Index != REG_NONE {
|
||||||
if a.Sym != nil {
|
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||||
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
|
str += s
|
||||||
} else {
|
|
||||||
|
|
||||||
str = fmt.Sprintf("%d(FP)", a.Offset)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_CONST:
|
case obj.TYPE_CONST:
|
||||||
str = fmt.Sprintf("$%d", a.Offset)
|
str = fmt.Sprintf("$%d", a.Offset)
|
||||||
|
|
||||||
case D_FCONST:
|
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
|
||||||
|
// SHRQ $32(DX*0), AX
|
||||||
|
// Remove.
|
||||||
|
if a.Index != REG_NONE {
|
||||||
|
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||||
|
str += s
|
||||||
|
}
|
||||||
|
|
||||||
|
case obj.TYPE_TEXTSIZE:
|
||||||
|
if a.U.Argsize == obj.ArgsSizeUnknown {
|
||||||
|
str = fmt.Sprintf("$%d", a.Offset)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
case obj.TYPE_FCONST:
|
||||||
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
|
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
|
||||||
|
|
||||||
case D_SCONST:
|
case obj.TYPE_SCONST:
|
||||||
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
||||||
|
|
||||||
case D_ADDR:
|
case obj.TYPE_ADDR:
|
||||||
a.Type = int16(a.Index)
|
a.Type = obj.TYPE_MEM
|
||||||
a.Index = D_NONE
|
|
||||||
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
|
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
|
||||||
a.Index = uint8(a.Type)
|
a.Type = obj.TYPE_ADDR
|
||||||
a.Type = D_ADDR
|
break
|
||||||
goto conv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
brk:
|
|
||||||
if a.Index != D_NONE {
|
|
||||||
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
|
||||||
str += s
|
|
||||||
}
|
|
||||||
|
|
||||||
conv:
|
|
||||||
fp += str
|
fp += str
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
@ -304,18 +306,22 @@ var Register = []string{
|
|||||||
"TR5",
|
"TR5",
|
||||||
"TR6",
|
"TR6",
|
||||||
"TR7",
|
"TR7",
|
||||||
"TLS", /* [D_TLS] */
|
"TLS", /* [D_TLS] */
|
||||||
"NONE", /* [D_NONE] */
|
"MAXREG", /* [MAXREG] */
|
||||||
}
|
}
|
||||||
|
|
||||||
func Rconv(r int) string {
|
func Rconv(r int) string {
|
||||||
var str string
|
var str string
|
||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
if r >= D_AL && r <= D_NONE {
|
if r == REG_NONE {
|
||||||
str = fmt.Sprintf("%s", Register[r-D_AL])
|
fp += "NONE"
|
||||||
} else {
|
return fp
|
||||||
|
}
|
||||||
|
|
||||||
|
if REG_AL <= r && r-REG_AL < len(Register) {
|
||||||
|
str = fmt.Sprintf("%s", Register[r-REG_AL])
|
||||||
|
} else {
|
||||||
str = fmt.Sprintf("gok(%d)", r)
|
str = fmt.Sprintf("gok(%d)", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -59,13 +59,13 @@ import (
|
|||||||
%token <lval> LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
|
%token <lval> LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
|
||||||
%token <lval> LCONST LSP LSB LFP LPC
|
%token <lval> LCONST LSP LSB LFP LPC
|
||||||
%token <lval> LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
|
%token <lval> LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
|
||||||
%token <lval> LCOND LS LAT
|
%token <lval> LCOND LS LAT LGLOBL
|
||||||
%token <dval> LFCONST
|
%token <dval> LFCONST
|
||||||
%token <sval> LSCONST
|
%token <sval> LSCONST
|
||||||
%token <sym> LNAME LLAB LVAR
|
%token <sym> LNAME LLAB LVAR
|
||||||
%type <lval> con expr oexpr pointer offset sreg spreg creg
|
%type <lval> con expr oexpr pointer offset sreg spreg creg
|
||||||
%type <lval> rcon cond reglist
|
%type <lval> rcon cond reglist
|
||||||
%type <addr> gen rel reg regreg freg shift fcon frcon
|
%type <addr> gen rel reg regreg freg shift fcon frcon textsize
|
||||||
%type <addr> imm ximm name oreg ireg nireg ioreg imsr
|
%type <addr> imm ximm name oreg ireg nireg ioreg imsr
|
||||||
%%
|
%%
|
||||||
prog:
|
prog:
|
||||||
@ -116,53 +116,53 @@ inst:
|
|||||||
}
|
}
|
||||||
| LTYPE1 cond imsr ',' reg
|
| LTYPE1 cond imsr ',' reg
|
||||||
{
|
{
|
||||||
outcode($1, $2, &$3, NREG, &$5);
|
outcode($1, $2, &$3, 0, &$5);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* MVN
|
* MVN
|
||||||
*/
|
*/
|
||||||
| LTYPE2 cond imsr ',' reg
|
| LTYPE2 cond imsr ',' reg
|
||||||
{
|
{
|
||||||
outcode($1, $2, &$3, NREG, &$5);
|
outcode($1, $2, &$3, 0, &$5);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* MOVW
|
* MOVW
|
||||||
*/
|
*/
|
||||||
| LTYPE3 cond gen ',' gen
|
| LTYPE3 cond gen ',' gen
|
||||||
{
|
{
|
||||||
outcode($1, $2, &$3, NREG, &$5);
|
outcode($1, $2, &$3, 0, &$5);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* B/BL
|
* B/BL
|
||||||
*/
|
*/
|
||||||
| LTYPE4 cond comma rel
|
| LTYPE4 cond comma rel
|
||||||
{
|
{
|
||||||
outcode($1, $2, &nullgen, NREG, &$4);
|
outcode($1, $2, &nullgen, 0, &$4);
|
||||||
}
|
}
|
||||||
| LTYPE4 cond comma nireg
|
| LTYPE4 cond comma nireg
|
||||||
{
|
{
|
||||||
outcode($1, $2, &nullgen, NREG, &$4);
|
outcode($1, $2, &nullgen, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* BX
|
* BX
|
||||||
*/
|
*/
|
||||||
| LTYPEBX comma ireg
|
| LTYPEBX comma ireg
|
||||||
{
|
{
|
||||||
outcode($1, Always, &nullgen, NREG, &$3);
|
outcode($1, Always, &nullgen, 0, &$3);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* BEQ
|
* BEQ
|
||||||
*/
|
*/
|
||||||
| LTYPE5 comma rel
|
| LTYPE5 comma rel
|
||||||
{
|
{
|
||||||
outcode($1, Always, &nullgen, NREG, &$3);
|
outcode($1, Always, &nullgen, 0, &$3);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* SWI
|
* SWI
|
||||||
*/
|
*/
|
||||||
| LTYPE6 cond comma gen
|
| LTYPE6 cond comma gen
|
||||||
{
|
{
|
||||||
outcode($1, $2, &nullgen, NREG, &$4);
|
outcode($1, $2, &nullgen, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* CMP
|
* CMP
|
||||||
@ -179,18 +179,18 @@ inst:
|
|||||||
var g obj.Addr
|
var g obj.Addr
|
||||||
|
|
||||||
g = nullgen;
|
g = nullgen;
|
||||||
g.Type = D_CONST;
|
g.Type = obj.TYPE_CONST;
|
||||||
g.Offset = int64($6);
|
g.Offset = int64($6);
|
||||||
outcode($1, $2, &$3, NREG, &g);
|
outcode($1, $2, &$3, 0, &g);
|
||||||
}
|
}
|
||||||
| LTYPE8 cond '[' reglist ']' ',' ioreg
|
| LTYPE8 cond '[' reglist ']' ',' ioreg
|
||||||
{
|
{
|
||||||
var g obj.Addr
|
var g obj.Addr
|
||||||
|
|
||||||
g = nullgen;
|
g = nullgen;
|
||||||
g.Type = D_CONST;
|
g.Type = obj.TYPE_CONST;
|
||||||
g.Offset = int64($4);
|
g.Offset = int64($4);
|
||||||
outcode($1, $2, &g, NREG, &$7);
|
outcode($1, $2, &g, 0, &$7);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* SWAP
|
* SWAP
|
||||||
@ -212,63 +212,78 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LTYPEA cond comma
|
| LTYPEA cond comma
|
||||||
{
|
{
|
||||||
outcode($1, $2, &nullgen, NREG, &nullgen);
|
outcode($1, $2, &nullgen, 0, &nullgen);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* TEXT/GLOBL
|
* TEXT
|
||||||
*/
|
*/
|
||||||
| LTYPEB name ',' imm
|
| LTYPEB name ',' '$' textsize
|
||||||
{
|
{
|
||||||
asm.Settext($2.Sym);
|
asm.Settext($2.Sym);
|
||||||
$4.Type = D_CONST2;
|
outcode($1, Always, &$2, 0, &$5);
|
||||||
$4.Offset2 = -obj.ArgsSizeUnknown;
|
|
||||||
outcode($1, Always, &$2, 0, &$4);
|
|
||||||
}
|
}
|
||||||
| LTYPEB name ',' con ',' imm
|
| LTYPEB name ',' con ',' '$' textsize
|
||||||
{
|
{
|
||||||
asm.Settext($2.Sym);
|
asm.Settext($2.Sym);
|
||||||
$6.Type = D_CONST2;
|
outcode($1, Always, &$2, 0, &$7);
|
||||||
$6.Offset2 = -obj.ArgsSizeUnknown;
|
if asm.Pass > 1 {
|
||||||
outcode($1, Always, &$2, $4, &$6);
|
lastpc.From3.Type = obj.TYPE_CONST;
|
||||||
|
lastpc.From3.Offset = int64($4)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| LTYPEB name ',' con ',' imm '-' con
|
/*
|
||||||
|
* GLOBL
|
||||||
|
*/
|
||||||
|
| LGLOBL name ',' imm
|
||||||
{
|
{
|
||||||
asm.Settext($2.Sym);
|
asm.Settext($2.Sym)
|
||||||
$6.Type = D_CONST2;
|
outcode($1, Always, &$2, 0, &$4)
|
||||||
$6.Offset2 = $8;
|
|
||||||
outcode($1, Always, &$2, $4, &$6);
|
|
||||||
}
|
}
|
||||||
|
| LGLOBL name ',' con ',' imm
|
||||||
|
{
|
||||||
|
asm.Settext($2.Sym)
|
||||||
|
outcode($1, Always, &$2, 0, &$6)
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = int64($4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DATA
|
* DATA
|
||||||
*/
|
*/
|
||||||
| LTYPEC name '/' con ',' ximm
|
| LTYPEC name '/' con ',' ximm
|
||||||
{
|
{
|
||||||
outcode($1, Always, &$2, $4, &$6);
|
outcode($1, Always, &$2, 0, &$6)
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = int64($4)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* CASE
|
* CASE
|
||||||
*/
|
*/
|
||||||
| LTYPED cond reg comma
|
| LTYPED cond reg comma
|
||||||
{
|
{
|
||||||
outcode($1, $2, &$3, NREG, &nullgen);
|
outcode($1, $2, &$3, 0, &nullgen);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* word
|
* word
|
||||||
*/
|
*/
|
||||||
| LTYPEH comma ximm
|
| LTYPEH comma ximm
|
||||||
{
|
{
|
||||||
outcode($1, Always, &nullgen, NREG, &$3);
|
outcode($1, Always, &nullgen, 0, &$3);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* floating-point coprocessor
|
* floating-point coprocessor
|
||||||
*/
|
*/
|
||||||
| LTYPEI cond freg ',' freg
|
| LTYPEI cond freg ',' freg
|
||||||
{
|
{
|
||||||
outcode($1, $2, &$3, NREG, &$5);
|
outcode($1, $2, &$3, 0, &$5);
|
||||||
}
|
}
|
||||||
| LTYPEK cond frcon ',' freg
|
| LTYPEK cond frcon ',' freg
|
||||||
{
|
{
|
||||||
outcode($1, $2, &$3, NREG, &$5);
|
outcode($1, $2, &$3, 0, &$5);
|
||||||
}
|
}
|
||||||
| LTYPEK cond frcon ',' LFREG ',' freg
|
| LTYPEK cond frcon ',' LFREG ',' freg
|
||||||
{
|
{
|
||||||
@ -286,11 +301,11 @@ inst:
|
|||||||
var g obj.Addr
|
var g obj.Addr
|
||||||
|
|
||||||
g = nullgen;
|
g = nullgen;
|
||||||
g.Type = D_CONST;
|
g.Type = obj.TYPE_CONST;
|
||||||
g.Offset = int64(
|
g.Offset = int64(
|
||||||
(0xe << 24) | /* opcode */
|
(0xe << 24) | /* opcode */
|
||||||
($1 << 20) | /* MCR/MRC */
|
($1 << 20) | /* MCR/MRC */
|
||||||
($2 << 28) | /* scond */
|
(($2^C_SCOND_XOR) << 28) | /* scond */
|
||||||
(($3 & 15) << 8) | /* coprocessor number */
|
(($3 & 15) << 8) | /* coprocessor number */
|
||||||
(($5 & 7) << 21) | /* coprocessor operation */
|
(($5 & 7) << 21) | /* coprocessor operation */
|
||||||
(($7 & 15) << 12) | /* arm register */
|
(($7 & 15) << 12) | /* arm register */
|
||||||
@ -298,7 +313,7 @@ inst:
|
|||||||
(($11 & 15) << 0) | /* Crm */
|
(($11 & 15) << 0) | /* Crm */
|
||||||
(($12 & 7) << 5) | /* coprocessor information */
|
(($12 & 7) << 5) | /* coprocessor information */
|
||||||
(1<<4)); /* must be set */
|
(1<<4)); /* must be set */
|
||||||
outcode(AMRC, Always, &nullgen, NREG, &g);
|
outcode(AMRC, Always, &nullgen, 0, &g);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* MULL r1,r2,(hi,lo)
|
* MULL r1,r2,(hi,lo)
|
||||||
@ -313,7 +328,7 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LTYPEN cond reg ',' reg ',' reg ',' spreg
|
| LTYPEN cond reg ',' reg ',' reg ',' spreg
|
||||||
{
|
{
|
||||||
$7.Type = D_REGREG2;
|
$7.Type = obj.TYPE_REGREG2;
|
||||||
$7.Offset = int64($9);
|
$7.Offset = int64($9);
|
||||||
outcode($1, $2, &$3, int32($5.Reg), &$7);
|
outcode($1, $2, &$3, int32($5.Reg), &$7);
|
||||||
}
|
}
|
||||||
@ -322,37 +337,67 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LTYPEPLD oreg
|
| LTYPEPLD oreg
|
||||||
{
|
{
|
||||||
outcode($1, Always, &$2, NREG, &nullgen);
|
outcode($1, Always, &$2, 0, &nullgen);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* PCDATA
|
* PCDATA
|
||||||
*/
|
*/
|
||||||
| LTYPEPC gen ',' gen
|
| LTYPEPC gen ',' gen
|
||||||
{
|
{
|
||||||
if $2.Type != D_CONST || $4.Type != D_CONST {
|
if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
|
||||||
yyerror("arguments to PCDATA must be integer constants")
|
yyerror("arguments to PCDATA must be integer constants")
|
||||||
}
|
}
|
||||||
outcode($1, Always, &$2, NREG, &$4);
|
outcode($1, Always, &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* FUNCDATA
|
* FUNCDATA
|
||||||
*/
|
*/
|
||||||
| LTYPEF gen ',' gen
|
| LTYPEF gen ',' gen
|
||||||
{
|
{
|
||||||
if $2.Type != D_CONST {
|
if $2.Type != obj.TYPE_CONST {
|
||||||
yyerror("index for FUNCDATA must be integer constant")
|
yyerror("index for FUNCDATA must be integer constant")
|
||||||
}
|
}
|
||||||
if $4.Type != D_EXTERN && $4.Type != D_STATIC && $4.Type != D_OREG {
|
if $4.Type != obj.NAME_EXTERN && $4.Type != obj.NAME_STATIC && $4.Type != obj.TYPE_MEM {
|
||||||
yyerror("value for FUNCDATA must be symbol reference")
|
yyerror("value for FUNCDATA must be symbol reference")
|
||||||
}
|
}
|
||||||
outcode($1, Always, &$2, NREG, &$4);
|
outcode($1, Always, &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* END
|
* END
|
||||||
*/
|
*/
|
||||||
| LTYPEE comma
|
| LTYPEE comma
|
||||||
{
|
{
|
||||||
outcode($1, Always, &nullgen, NREG, &nullgen);
|
outcode($1, Always, &nullgen, 0, &nullgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
textsize:
|
||||||
|
LCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = int64($1)
|
||||||
|
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||||
|
}
|
||||||
|
| '-' LCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = -int64($2)
|
||||||
|
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||||
|
}
|
||||||
|
| LCONST '-' LCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = int64($1)
|
||||||
|
$$.U.Argsize = int32($3);
|
||||||
|
}
|
||||||
|
| '-' LCONST '-' LCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = -int64($2)
|
||||||
|
$$.U.Argsize = int32($4);
|
||||||
}
|
}
|
||||||
|
|
||||||
cond:
|
cond:
|
||||||
@ -375,7 +420,7 @@ rel:
|
|||||||
con '(' LPC ')'
|
con '(' LPC ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_BRANCH;
|
$$.Type = obj.TYPE_BRANCH;
|
||||||
$$.Offset = int64($1) + int64(asm.PC);
|
$$.Offset = int64($1) + int64(asm.PC);
|
||||||
}
|
}
|
||||||
| LNAME offset
|
| LNAME offset
|
||||||
@ -385,30 +430,25 @@ rel:
|
|||||||
if asm.Pass == 2 && $1.Type != LLAB {
|
if asm.Pass == 2 && $1.Type != LLAB {
|
||||||
yyerror("undefined label: %s", $1.Labelname)
|
yyerror("undefined label: %s", $1.Labelname)
|
||||||
}
|
}
|
||||||
$$.Type = D_BRANCH;
|
$$.Type = obj.TYPE_BRANCH;
|
||||||
$$.Offset = $1.Value + int64($2);
|
$$.Offset = $1.Value + int64($2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ximm: '$' con
|
ximm: '$' con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_CONST;
|
$$.Type = obj.TYPE_CONST;
|
||||||
$$.Offset = int64($2);
|
$$.Offset = int64($2);
|
||||||
}
|
}
|
||||||
| '$' oreg
|
| '$' oreg
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
$$.Type = D_CONST;
|
$$.Type = obj.TYPE_ADDR;
|
||||||
}
|
|
||||||
| '$' '*' '$' oreg
|
|
||||||
{
|
|
||||||
$$ = $4;
|
|
||||||
$$.Type = D_OCONST;
|
|
||||||
}
|
}
|
||||||
| '$' LSCONST
|
| '$' LSCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SCONST;
|
$$.Type = obj.TYPE_SCONST;
|
||||||
$$.U.Sval = $2
|
$$.U.Sval = $2
|
||||||
}
|
}
|
||||||
| fcon
|
| fcon
|
||||||
@ -417,34 +457,34 @@ fcon:
|
|||||||
'$' LFCONST
|
'$' LFCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = $2;
|
$$.U.Dval = $2;
|
||||||
}
|
}
|
||||||
| '$' '-' LFCONST
|
| '$' '-' LFCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = -$3;
|
$$.U.Dval = -$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
reglist:
|
reglist:
|
||||||
spreg
|
spreg
|
||||||
{
|
{
|
||||||
$$ = 1 << uint($1);
|
$$ = 1 << uint($1&15);
|
||||||
}
|
}
|
||||||
| spreg '-' spreg
|
| spreg '-' spreg
|
||||||
{
|
{
|
||||||
$$=0;
|
$$=0;
|
||||||
for i:=$1; i<=$3; i++ {
|
for i:=$1; i<=$3; i++ {
|
||||||
$$ |= 1<<uint(i)
|
$$ |= 1<<uint(i&15)
|
||||||
}
|
}
|
||||||
for i:=$3; i<=$1; i++ {
|
for i:=$3; i<=$1; i++ {
|
||||||
$$ |= 1<<uint(i)
|
$$ |= 1<<uint(i&15)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| spreg comma reglist
|
| spreg comma reglist
|
||||||
{
|
{
|
||||||
$$ = (1<<uint($1)) | $3;
|
$$ = (1<<uint($1&15)) | $3;
|
||||||
}
|
}
|
||||||
|
|
||||||
gen:
|
gen:
|
||||||
@ -454,24 +494,24 @@ gen:
|
|||||||
| shift '(' spreg ')'
|
| shift '(' spreg ')'
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.Reg = int8($3);
|
$$.Reg = int16($3);
|
||||||
}
|
}
|
||||||
| LPSR
|
| LPSR
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_PSR;
|
$$.Type = obj.TYPE_REG
|
||||||
$$.Reg = int8($1);
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LFCR
|
| LFCR
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FPCR;
|
$$.Type = obj.TYPE_REG
|
||||||
$$.Reg = int8($1);
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| con
|
| con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Offset = int64($1);
|
$$.Offset = int64($1);
|
||||||
}
|
}
|
||||||
| oreg
|
| oreg
|
||||||
@ -482,7 +522,7 @@ nireg:
|
|||||||
| name
|
| name
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
if($1.Name != D_EXTERN && $1.Name != D_STATIC) {
|
if($1.Name != obj.NAME_EXTERN && $1.Name != obj.NAME_STATIC) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,8 +530,8 @@ ireg:
|
|||||||
'(' spreg ')'
|
'(' spreg ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Reg = int8($2);
|
$$.Reg = int16($2);
|
||||||
$$.Offset = 0;
|
$$.Offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,8 +540,8 @@ ioreg:
|
|||||||
| con '(' sreg ')'
|
| con '(' sreg ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Reg = int8($3);
|
$$.Reg = int16($3);
|
||||||
$$.Offset = int64($1);
|
$$.Offset = int64($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,8 +550,8 @@ oreg:
|
|||||||
| name '(' sreg ')'
|
| name '(' sreg ')'
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Reg = int8($3);
|
$$.Reg = int16($3);
|
||||||
}
|
}
|
||||||
| ioreg
|
| ioreg
|
||||||
|
|
||||||
@ -523,7 +563,7 @@ imsr:
|
|||||||
imm: '$' con
|
imm: '$' con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_CONST;
|
$$.Type = obj.TYPE_CONST;
|
||||||
$$.Offset = int64($2);
|
$$.Offset = int64($2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,16 +571,16 @@ reg:
|
|||||||
spreg
|
spreg
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_REG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($1);
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
regreg:
|
regreg:
|
||||||
'(' spreg ',' spreg ')'
|
'(' spreg ',' spreg ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_REGREG;
|
$$.Type = obj.TYPE_REGREG;
|
||||||
$$.Reg = int8($2);
|
$$.Reg = int16($2);
|
||||||
$$.Offset = int64($4);
|
$$.Offset = int64($4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,32 +588,32 @@ shift:
|
|||||||
spreg '<' '<' rcon
|
spreg '<' '<' rcon
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SHIFT;
|
$$.Type = obj.TYPE_SHIFT;
|
||||||
$$.Offset = int64($1) | int64($4) | (0 << 5);
|
$$.Offset = int64($1&15) | int64($4) | (0 << 5);
|
||||||
}
|
}
|
||||||
| spreg '>' '>' rcon
|
| spreg '>' '>' rcon
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SHIFT;
|
$$.Type = obj.TYPE_SHIFT;
|
||||||
$$.Offset = int64($1) | int64($4) | (1 << 5);
|
$$.Offset = int64($1&15) | int64($4) | (1 << 5);
|
||||||
}
|
}
|
||||||
| spreg '-' '>' rcon
|
| spreg '-' '>' rcon
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SHIFT;
|
$$.Type = obj.TYPE_SHIFT;
|
||||||
$$.Offset = int64($1) | int64($4) | (2 << 5);
|
$$.Offset = int64($1&15) | int64($4) | (2 << 5);
|
||||||
}
|
}
|
||||||
| spreg LAT '>' rcon
|
| spreg LAT '>' rcon
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SHIFT;
|
$$.Type = obj.TYPE_SHIFT;
|
||||||
$$.Offset = int64($1) | int64($4) | (3 << 5);
|
$$.Offset = int64($1&15) | int64($4) | (3 << 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
rcon:
|
rcon:
|
||||||
spreg
|
spreg
|
||||||
{
|
{
|
||||||
if $$ < 0 || $$ >= 16 {
|
if $$ < REG_R0 || $$ > REG_R15 {
|
||||||
print("register value out of range\n")
|
print("register value out of range\n")
|
||||||
}
|
}
|
||||||
$$ = (($1&15) << 8) | (1 << 4);
|
$$ = (($1&15) << 8) | (1 << 4);
|
||||||
@ -597,7 +637,7 @@ sreg:
|
|||||||
if $3 < 0 || $3 >= NREG {
|
if $3 < 0 || $3 >= NREG {
|
||||||
print("register value out of range\n")
|
print("register value out of range\n")
|
||||||
}
|
}
|
||||||
$$ = $3;
|
$$ = REG_R0 + $3;
|
||||||
}
|
}
|
||||||
|
|
||||||
spreg:
|
spreg:
|
||||||
@ -614,7 +654,7 @@ creg:
|
|||||||
if $3 < 0 || $3 >= NREG {
|
if $3 < 0 || $3 >= NREG {
|
||||||
print("register value out of range\n")
|
print("register value out of range\n")
|
||||||
}
|
}
|
||||||
$$ = $3;
|
$$ = $3; // TODO(rsc): REG_C0+$3
|
||||||
}
|
}
|
||||||
|
|
||||||
frcon:
|
frcon:
|
||||||
@ -625,21 +665,21 @@ freg:
|
|||||||
LFREG
|
LFREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FREG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($1);
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LF '(' con ')'
|
| LF '(' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FREG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($3);
|
$$.Reg = int16(REG_F0 + $3);
|
||||||
}
|
}
|
||||||
|
|
||||||
name:
|
name:
|
||||||
con '(' pointer ')'
|
con '(' pointer ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Name = int8($3);
|
$$.Name = int8($3);
|
||||||
$$.Sym = nil;
|
$$.Sym = nil;
|
||||||
$$.Offset = int64($1);
|
$$.Offset = int64($1);
|
||||||
@ -647,7 +687,7 @@ name:
|
|||||||
| LNAME offset '(' pointer ')'
|
| LNAME offset '(' pointer ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Name = int8($4);
|
$$.Name = int8($4);
|
||||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||||
$$.Offset = int64($2);
|
$$.Offset = int64($2);
|
||||||
@ -655,8 +695,8 @@ name:
|
|||||||
| LNAME '<' '>' offset '(' LSB ')'
|
| LNAME '<' '>' offset '(' LSB ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Name = D_STATIC;
|
$$.Name = obj.NAME_STATIC;
|
||||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
||||||
$$.Offset = int64($4);
|
$$.Offset = int64($4);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ var (
|
|||||||
stmtline int32
|
stmtline int32
|
||||||
)
|
)
|
||||||
|
|
||||||
const Always = 14
|
const Always = arm.C_SCOND_NONE
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cinit()
|
cinit()
|
||||||
@ -88,44 +88,46 @@ func yyparse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lexinit = []asm.Lextab{
|
var lexinit = []asm.Lextab{
|
||||||
{"SP", LSP, arm.D_AUTO},
|
{"SP", LSP, obj.NAME_AUTO},
|
||||||
{"SB", LSB, arm.D_EXTERN},
|
{"SB", LSB, obj.NAME_EXTERN},
|
||||||
{"FP", LFP, arm.D_PARAM},
|
{"FP", LFP, obj.NAME_PARAM},
|
||||||
{"PC", LPC, arm.D_BRANCH},
|
{"PC", LPC, obj.TYPE_BRANCH},
|
||||||
|
|
||||||
{"R", LR, 0},
|
{"R", LR, 0},
|
||||||
{"R0", LREG, 0},
|
|
||||||
{"R1", LREG, 1},
|
{"R0", LREG, arm.REG_R0},
|
||||||
{"R2", LREG, 2},
|
{"R1", LREG, arm.REG_R1},
|
||||||
{"R3", LREG, 3},
|
{"R2", LREG, arm.REG_R2},
|
||||||
{"R4", LREG, 4},
|
{"R3", LREG, arm.REG_R3},
|
||||||
{"R5", LREG, 5},
|
{"R4", LREG, arm.REG_R4},
|
||||||
{"R6", LREG, 6},
|
{"R5", LREG, arm.REG_R5},
|
||||||
{"R7", LREG, 7},
|
{"R6", LREG, arm.REG_R6},
|
||||||
{"R8", LREG, 8},
|
{"R7", LREG, arm.REG_R7},
|
||||||
{"R9", LREG, 9},
|
{"R8", LREG, arm.REG_R8},
|
||||||
{"g", LREG, 10}, // avoid unintentionally clobber g using R10
|
{"R9", LREG, arm.REG_R9},
|
||||||
{"R11", LREG, 11},
|
{"g", LREG, arm.REG_R10}, // avoid unintentionally clobber g using R10
|
||||||
{"R12", LREG, 12},
|
{"R11", LREG, arm.REG_R11},
|
||||||
{"R13", LREG, 13},
|
{"R12", LREG, arm.REG_R12},
|
||||||
{"R14", LREG, 14},
|
{"R13", LREG, arm.REG_R13},
|
||||||
{"R15", LREG, 15},
|
{"R14", LREG, arm.REG_R14},
|
||||||
|
{"R15", LREG, arm.REG_R15},
|
||||||
{"F", LF, 0},
|
{"F", LF, 0},
|
||||||
{"F0", LFREG, 0},
|
{"F0", LFREG, arm.REG_F0},
|
||||||
{"F1", LFREG, 1},
|
{"F1", LFREG, arm.REG_F1},
|
||||||
{"F2", LFREG, 2},
|
{"F2", LFREG, arm.REG_F2},
|
||||||
{"F3", LFREG, 3},
|
{"F3", LFREG, arm.REG_F3},
|
||||||
{"F4", LFREG, 4},
|
{"F4", LFREG, arm.REG_F4},
|
||||||
{"F5", LFREG, 5},
|
{"F5", LFREG, arm.REG_F5},
|
||||||
{"F6", LFREG, 6},
|
{"F6", LFREG, arm.REG_F6},
|
||||||
{"F7", LFREG, 7},
|
{"F7", LFREG, arm.REG_F7},
|
||||||
{"F8", LFREG, 8},
|
{"F8", LFREG, arm.REG_F8},
|
||||||
{"F9", LFREG, 9},
|
{"F9", LFREG, arm.REG_F9},
|
||||||
{"F10", LFREG, 10},
|
{"F10", LFREG, arm.REG_F10},
|
||||||
{"F11", LFREG, 11},
|
{"F11", LFREG, arm.REG_F11},
|
||||||
{"F12", LFREG, 12},
|
{"F12", LFREG, arm.REG_F12},
|
||||||
{"F13", LFREG, 13},
|
{"F13", LFREG, arm.REG_F13},
|
||||||
{"F14", LFREG, 14},
|
{"F14", LFREG, arm.REG_F14},
|
||||||
{"F15", LFREG, 15},
|
{"F15", LFREG, arm.REG_F15},
|
||||||
{"C", LC, 0},
|
{"C", LC, 0},
|
||||||
{"C0", LCREG, 0},
|
{"C0", LCREG, 0},
|
||||||
{"C1", LCREG, 1},
|
{"C1", LCREG, 1},
|
||||||
@ -143,27 +145,27 @@ var lexinit = []asm.Lextab{
|
|||||||
{"C13", LCREG, 13},
|
{"C13", LCREG, 13},
|
||||||
{"C14", LCREG, 14},
|
{"C14", LCREG, 14},
|
||||||
{"C15", LCREG, 15},
|
{"C15", LCREG, 15},
|
||||||
{"CPSR", LPSR, 0},
|
{"CPSR", LPSR, arm.REG_CPSR},
|
||||||
{"SPSR", LPSR, 1},
|
{"SPSR", LPSR, arm.REG_SPSR},
|
||||||
{"FPSR", LFCR, 0},
|
{"FPSR", LFCR, arm.REG_FPSR},
|
||||||
{"FPCR", LFCR, 1},
|
{"FPCR", LFCR, arm.REG_FPCR},
|
||||||
{".EQ", LCOND, 0},
|
{".EQ", LCOND, arm.C_SCOND_EQ},
|
||||||
{".NE", LCOND, 1},
|
{".NE", LCOND, arm.C_SCOND_NE},
|
||||||
{".CS", LCOND, 2},
|
{".CS", LCOND, arm.C_SCOND_HS},
|
||||||
{".HS", LCOND, 2},
|
{".HS", LCOND, arm.C_SCOND_HS},
|
||||||
{".CC", LCOND, 3},
|
{".CC", LCOND, arm.C_SCOND_LO},
|
||||||
{".LO", LCOND, 3},
|
{".LO", LCOND, arm.C_SCOND_LO},
|
||||||
{".MI", LCOND, 4},
|
{".MI", LCOND, arm.C_SCOND_MI},
|
||||||
{".PL", LCOND, 5},
|
{".PL", LCOND, arm.C_SCOND_PL},
|
||||||
{".VS", LCOND, 6},
|
{".VS", LCOND, arm.C_SCOND_VS},
|
||||||
{".VC", LCOND, 7},
|
{".VC", LCOND, arm.C_SCOND_VC},
|
||||||
{".HI", LCOND, 8},
|
{".HI", LCOND, arm.C_SCOND_HI},
|
||||||
{".LS", LCOND, 9},
|
{".LS", LCOND, arm.C_SCOND_LS},
|
||||||
{".GE", LCOND, 10},
|
{".GE", LCOND, arm.C_SCOND_GE},
|
||||||
{".LT", LCOND, 11},
|
{".LT", LCOND, arm.C_SCOND_LT},
|
||||||
{".GT", LCOND, 12},
|
{".GT", LCOND, arm.C_SCOND_GT},
|
||||||
{".LE", LCOND, 13},
|
{".LE", LCOND, arm.C_SCOND_LE},
|
||||||
{".AL", LCOND, Always},
|
{".AL", LCOND, arm.C_SCOND_NONE},
|
||||||
{".U", LS, arm.C_UBIT},
|
{".U", LS, arm.C_UBIT},
|
||||||
{".S", LS, arm.C_SBIT},
|
{".S", LS, arm.C_SBIT},
|
||||||
{".W", LS, arm.C_WBIT},
|
{".W", LS, arm.C_WBIT},
|
||||||
@ -274,33 +276,30 @@ var lexinit = []asm.Lextab{
|
|||||||
{"MOVM", LTYPE8, arm.AMOVM},
|
{"MOVM", LTYPE8, arm.AMOVM},
|
||||||
{"SWPBU", LTYPE9, arm.ASWPBU},
|
{"SWPBU", LTYPE9, arm.ASWPBU},
|
||||||
{"SWPW", LTYPE9, arm.ASWPW},
|
{"SWPW", LTYPE9, arm.ASWPW},
|
||||||
{"RET", LTYPEA, arm.ARET},
|
{"RET", LTYPEA, obj.ARET},
|
||||||
{"RFE", LTYPEA, arm.ARFE},
|
{"RFE", LTYPEA, arm.ARFE},
|
||||||
{"TEXT", LTYPEB, arm.ATEXT},
|
{"TEXT", LTYPEB, obj.ATEXT},
|
||||||
{"GLOBL", LTYPEB, arm.AGLOBL},
|
{"GLOBL", LGLOBL, obj.AGLOBL},
|
||||||
{"DATA", LTYPEC, arm.ADATA},
|
{"DATA", LTYPEC, obj.ADATA},
|
||||||
{"CASE", LTYPED, arm.ACASE},
|
{"CASE", LTYPED, arm.ACASE},
|
||||||
{"END", LTYPEE, arm.AEND},
|
{"END", LTYPEE, obj.AEND},
|
||||||
{"WORD", LTYPEH, arm.AWORD},
|
{"WORD", LTYPEH, arm.AWORD},
|
||||||
{"NOP", LTYPEI, arm.ANOP},
|
{"NOP", LTYPEI, obj.ANOP},
|
||||||
{"MCR", LTYPEJ, 0},
|
{"MCR", LTYPEJ, 0},
|
||||||
{"MRC", LTYPEJ, 1},
|
{"MRC", LTYPEJ, 1},
|
||||||
{"PLD", LTYPEPLD, arm.APLD},
|
{"PLD", LTYPEPLD, arm.APLD},
|
||||||
{"UNDEF", LTYPEE, arm.AUNDEF},
|
{"UNDEF", LTYPEE, obj.AUNDEF},
|
||||||
{"CLZ", LTYPE2, arm.ACLZ},
|
{"CLZ", LTYPE2, arm.ACLZ},
|
||||||
{"MULWT", LTYPE1, arm.AMULWT},
|
{"MULWT", LTYPE1, arm.AMULWT},
|
||||||
{"MULWB", LTYPE1, arm.AMULWB},
|
{"MULWB", LTYPE1, arm.AMULWB},
|
||||||
{"MULAWT", LTYPEN, arm.AMULAWT},
|
{"MULAWT", LTYPEN, arm.AMULAWT},
|
||||||
{"MULAWB", LTYPEN, arm.AMULAWB},
|
{"MULAWB", LTYPEN, arm.AMULAWB},
|
||||||
{"USEFIELD", LTYPEN, arm.AUSEFIELD},
|
{"USEFIELD", LTYPEN, obj.AUSEFIELD},
|
||||||
{"PCDATA", LTYPEPC, arm.APCDATA},
|
{"PCDATA", LTYPEPC, obj.APCDATA},
|
||||||
{"FUNCDATA", LTYPEF, arm.AFUNCDATA},
|
{"FUNCDATA", LTYPEF, obj.AFUNCDATA},
|
||||||
}
|
}
|
||||||
|
|
||||||
func cinit() {
|
func cinit() {
|
||||||
nullgen.Type = arm.D_NONE
|
|
||||||
nullgen.Name = arm.D_NONE
|
|
||||||
nullgen.Reg = arm.NREG
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isreg(g *obj.Addr) bool {
|
func isreg(g *obj.Addr) bool {
|
||||||
@ -308,7 +307,7 @@ func isreg(g *obj.Addr) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func cclean() {
|
func cclean() {
|
||||||
outcode(arm.AEND, Always, &nullgen, arm.NREG, &nullgen)
|
outcode(obj.AEND, Always, &nullgen, 0, &nullgen)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bcode = []int{
|
var bcode = []int{
|
||||||
@ -327,7 +326,7 @@ var bcode = []int{
|
|||||||
arm.ABGT,
|
arm.ABGT,
|
||||||
arm.ABLE,
|
arm.ABLE,
|
||||||
arm.AB,
|
arm.AB,
|
||||||
arm.ANOP,
|
obj.ANOP,
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastpc *obj.Prog
|
var lastpc *obj.Prog
|
||||||
@ -338,7 +337,7 @@ func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
|
|||||||
|
|
||||||
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
|
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
|
||||||
if a == arm.AB {
|
if a == arm.AB {
|
||||||
a = int32(bcode[scond&0xf])
|
a = int32(bcode[(scond^arm.C_SCOND_XOR)&0xf])
|
||||||
scond = (scond &^ 0xf) | Always
|
scond = (scond &^ 0xf) | Always
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +352,7 @@ func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
|
|||||||
p.Lineno = stmtline
|
p.Lineno = stmtline
|
||||||
p.Scond = uint8(scond)
|
p.Scond = uint8(scond)
|
||||||
p.From = *g1
|
p.From = *g1
|
||||||
p.Reg = uint8(reg)
|
p.Reg = int16(reg)
|
||||||
p.To = *g2
|
p.To = *g2
|
||||||
p.Pc = int64(asm.PC)
|
p.Pc = int64(asm.PC)
|
||||||
|
|
||||||
@ -366,7 +365,7 @@ func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
|
|||||||
lastpc = p
|
lastpc = p
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if a != arm.AGLOBL && a != arm.ADATA {
|
if a != obj.AGLOBL && a != obj.ADATA {
|
||||||
asm.PC++
|
asm.PC++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1121
src/cmd/new5a/y.go
1121
src/cmd/new5a/y.go
File diff suppressed because it is too large
Load Diff
@ -61,11 +61,11 @@ import (
|
|||||||
%token <dval> LFCONST
|
%token <dval> LFCONST
|
||||||
%token <sval> LSCONST LSP
|
%token <sval> LSCONST LSP
|
||||||
%token <sym> LNAME LLAB LVAR
|
%token <sym> LNAME LLAB LVAR
|
||||||
%type <lval> con con2 expr pointer offset
|
%type <lval> con expr pointer offset
|
||||||
%type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
|
%type <addr> mem imm textsize reg nam rel rem rim rom omem nmem
|
||||||
%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
|
%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
|
||||||
%type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
|
%type <addr2> spec3 spec4 spec5 spec6 spec7 spec8 spec9
|
||||||
%type <addr2> spec10 spec11 spec12 spec13
|
%type <addr2> spec10 spec12 spec13
|
||||||
%%
|
%%
|
||||||
prog:
|
prog:
|
||||||
| prog
|
| prog
|
||||||
@ -108,8 +108,8 @@ inst:
|
|||||||
| LTYPE3 rimrem { outcode(int($1), &$2); }
|
| LTYPE3 rimrem { outcode(int($1), &$2); }
|
||||||
| LTYPE4 remrim { outcode(int($1), &$2); }
|
| LTYPE4 remrim { outcode(int($1), &$2); }
|
||||||
| LTYPER nonrel { outcode(int($1), &$2); }
|
| LTYPER nonrel { outcode(int($1), &$2); }
|
||||||
| LTYPED spec1 { outcode(int($1), &$2); }
|
| spec1
|
||||||
| LTYPET spec2 { outcode(int($1), &$2); }
|
| spec2
|
||||||
| LTYPEC spec3 { outcode(int($1), &$2); }
|
| LTYPEC spec3 { outcode(int($1), &$2); }
|
||||||
| LTYPEN spec4 { outcode(int($1), &$2); }
|
| LTYPEN spec4 { outcode(int($1), &$2); }
|
||||||
| LTYPES spec5 { outcode(int($1), &$2); }
|
| LTYPES spec5 { outcode(int($1), &$2); }
|
||||||
@ -118,7 +118,7 @@ inst:
|
|||||||
| LTYPEXC spec8 { outcode(int($1), &$2); }
|
| LTYPEXC spec8 { outcode(int($1), &$2); }
|
||||||
| LTYPEX spec9 { outcode(int($1), &$2); }
|
| LTYPEX spec9 { outcode(int($1), &$2); }
|
||||||
| LTYPERT spec10 { outcode(int($1), &$2); }
|
| LTYPERT spec10 { outcode(int($1), &$2); }
|
||||||
| LTYPEG spec11 { outcode(int($1), &$2); }
|
| spec11
|
||||||
| LTYPEPC spec12 { outcode(int($1), &$2); }
|
| LTYPEPC spec12 { outcode(int($1), &$2); }
|
||||||
| LTYPEF spec13 { outcode(int($1), &$2); }
|
| LTYPEF spec13 { outcode(int($1), &$2); }
|
||||||
|
|
||||||
@ -189,26 +189,48 @@ nonrel:
|
|||||||
}
|
}
|
||||||
|
|
||||||
spec1: /* DATA */
|
spec1: /* DATA */
|
||||||
nam '/' con ',' imm
|
LTYPED nam '/' con ',' imm
|
||||||
{
|
{
|
||||||
$$.from = $1;
|
var a Addr2
|
||||||
$$.from.Scale = int8($3);
|
a.from = $2
|
||||||
$$.to = $5;
|
a.to = $6
|
||||||
|
outcode(obj.ADATA, &a)
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spec2: /* TEXT */
|
spec2: /* TEXT */
|
||||||
mem ',' imm2
|
LTYPET mem ',' '$' textsize
|
||||||
{
|
{
|
||||||
asm.Settext($1.Sym);
|
asm.Settext($2.Sym);
|
||||||
$$.from = $1;
|
outcode(obj.ATEXT, &Addr2{$2, $5})
|
||||||
$$.to = $3;
|
|
||||||
}
|
}
|
||||||
| mem ',' con ',' imm2
|
| LTYPET mem ',' con ',' '$' textsize
|
||||||
{
|
{
|
||||||
asm.Settext($1.Sym);
|
asm.Settext($2.Sym);
|
||||||
$$.from = $1;
|
outcode(obj.ATEXT, &Addr2{$2, $7})
|
||||||
$$.from.Scale = int8($3);
|
if asm.Pass > 1 {
|
||||||
$$.to = $5;
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spec11: /* GLOBL */
|
||||||
|
LTYPEG mem ',' imm
|
||||||
|
{
|
||||||
|
asm.Settext($2.Sym)
|
||||||
|
outcode(obj.AGLOBL, &Addr2{$2, $4})
|
||||||
|
}
|
||||||
|
| LTYPEG mem ',' con ',' imm
|
||||||
|
{
|
||||||
|
asm.Settext($2.Sym)
|
||||||
|
outcode(obj.AGLOBL, &Addr2{$2, $6})
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spec3: /* JMP/CALL */
|
spec3: /* JMP/CALL */
|
||||||
@ -237,10 +259,10 @@ spec5: /* SHL/SHR */
|
|||||||
{
|
{
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
if $$.from.Index != x86.D_NONE {
|
if $$.from.Index != obj.TYPE_NONE {
|
||||||
yyerror("dp shift with lhs index");
|
yyerror("dp shift with lhs index");
|
||||||
}
|
}
|
||||||
$$.from.Index = uint8($5);
|
$$.from.Index = int16($5);
|
||||||
}
|
}
|
||||||
|
|
||||||
spec6: /* MOVW/MOVL */
|
spec6: /* MOVW/MOVL */
|
||||||
@ -253,10 +275,10 @@ spec6: /* MOVW/MOVL */
|
|||||||
{
|
{
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
if $$.to.Index != x86.D_NONE {
|
if $$.to.Index != obj.TYPE_NONE {
|
||||||
yyerror("dp move with lhs index");
|
yyerror("dp move with lhs index");
|
||||||
}
|
}
|
||||||
$$.to.Index = uint8($5);
|
$$.to.Index = int16($5);
|
||||||
}
|
}
|
||||||
|
|
||||||
spec7:
|
spec7:
|
||||||
@ -289,7 +311,7 @@ spec9: /* shufl */
|
|||||||
{
|
{
|
||||||
$$.from = $3;
|
$$.from = $3;
|
||||||
$$.to = $5;
|
$$.to = $5;
|
||||||
if $1.Type != x86.D_CONST {
|
if $1.Type != obj.TYPE_CONST {
|
||||||
yyerror("illegal constant");
|
yyerror("illegal constant");
|
||||||
}
|
}
|
||||||
$$.to.Offset = $1.Offset;
|
$$.to.Offset = $1.Offset;
|
||||||
@ -306,23 +328,10 @@ spec10: /* RET/RETF */
|
|||||||
$$.to = nullgen;
|
$$.to = nullgen;
|
||||||
}
|
}
|
||||||
|
|
||||||
spec11: /* GLOBL */
|
|
||||||
mem ',' imm
|
|
||||||
{
|
|
||||||
$$.from = $1;
|
|
||||||
$$.to = $3;
|
|
||||||
}
|
|
||||||
| mem ',' con ',' imm
|
|
||||||
{
|
|
||||||
$$.from = $1;
|
|
||||||
$$.from.Scale = int8($3);
|
|
||||||
$$.to = $5;
|
|
||||||
}
|
|
||||||
|
|
||||||
spec12: /* asm.PCDATA */
|
spec12: /* asm.PCDATA */
|
||||||
rim ',' rim
|
rim ',' rim
|
||||||
{
|
{
|
||||||
if $1.Type != x86.D_CONST || $3.Type != x86.D_CONST {
|
if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
|
||||||
yyerror("arguments to asm.PCDATA must be integer constants");
|
yyerror("arguments to asm.PCDATA must be integer constants");
|
||||||
}
|
}
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
@ -332,10 +341,10 @@ spec12: /* asm.PCDATA */
|
|||||||
spec13: /* FUNCDATA */
|
spec13: /* FUNCDATA */
|
||||||
rim ',' rim
|
rim ',' rim
|
||||||
{
|
{
|
||||||
if $1.Type != x86.D_CONST {
|
if $1.Type != obj.TYPE_CONST {
|
||||||
yyerror("index for FUNCDATA must be integer constant");
|
yyerror("index for FUNCDATA must be integer constant");
|
||||||
}
|
}
|
||||||
if $3.Type != x86.D_EXTERN && $3.Type != x86.D_STATIC {
|
if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
|
||||||
yyerror("value for FUNCDATA must be symbol reference");
|
yyerror("value for FUNCDATA must be symbol reference");
|
||||||
}
|
}
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
@ -368,7 +377,7 @@ rel:
|
|||||||
con '(' LPC ')'
|
con '(' LPC ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_BRANCH;
|
$$.Type = obj.TYPE_BRANCH;
|
||||||
$$.Offset = $1 + int64(asm.PC);
|
$$.Offset = $1 + int64(asm.PC);
|
||||||
}
|
}
|
||||||
| LNAME offset
|
| LNAME offset
|
||||||
@ -378,7 +387,7 @@ rel:
|
|||||||
if asm.Pass == 2 && $1.Type != LLAB {
|
if asm.Pass == 2 && $1.Type != LLAB {
|
||||||
yyerror("undefined label: %s", $1.Labelname);
|
yyerror("undefined label: %s", $1.Labelname);
|
||||||
}
|
}
|
||||||
$$.Type = x86.D_BRANCH;
|
$$.Type = obj.TYPE_BRANCH;
|
||||||
$$.Offset = $1.Value + $2;
|
$$.Offset = $1.Value + $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,58 +395,57 @@ reg:
|
|||||||
LBREG
|
LBREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LFREG
|
| LFREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LLREG
|
| LLREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LMREG
|
| LMREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LSP
|
| LSP
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_SP;
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = x86.REG_SP;
|
||||||
}
|
}
|
||||||
| LSREG
|
| LSREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LXREG
|
| LXREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
}
|
$$.Reg = int16($1);
|
||||||
imm2:
|
|
||||||
'$' con2
|
|
||||||
{
|
|
||||||
$$ = nullgen;
|
|
||||||
$$.Type = x86.D_CONST;
|
|
||||||
$$.Offset = $2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imm:
|
imm:
|
||||||
'$' con
|
'$' con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_CONST;
|
$$.Type = obj.TYPE_CONST;
|
||||||
$$.Offset = $2;
|
$$.Offset = $2;
|
||||||
}
|
}
|
||||||
| '$' nam
|
| '$' nam
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
$$.Index = uint8($2.Type);
|
$$.Type = obj.TYPE_ADDR;
|
||||||
$$.Type = x86.D_ADDR;
|
|
||||||
/*
|
/*
|
||||||
if($2.Type == x86.D_AUTO || $2.Type == x86.D_PARAM)
|
if($2.Type == x86.D_AUTO || $2.Type == x86.D_PARAM)
|
||||||
yyerror("constant cannot be automatic: %s",
|
yyerror("constant cannot be automatic: %s",
|
||||||
@ -447,31 +455,31 @@ imm:
|
|||||||
| '$' LSCONST
|
| '$' LSCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_SCONST;
|
$$.Type = obj.TYPE_SCONST;
|
||||||
$$.U.Sval = ($2+"\x00\x00\x00\x00\x00\x00\x00\x00")[:8]
|
$$.U.Sval = ($2+"\x00\x00\x00\x00\x00\x00\x00\x00")[:8]
|
||||||
}
|
}
|
||||||
| '$' LFCONST
|
| '$' LFCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = $2;
|
$$.U.Dval = $2;
|
||||||
}
|
}
|
||||||
| '$' '(' LFCONST ')'
|
| '$' '(' LFCONST ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = $3;
|
$$.U.Dval = $3;
|
||||||
}
|
}
|
||||||
| '$' '(' '-' LFCONST ')'
|
| '$' '(' '-' LFCONST ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = -$4;
|
$$.U.Dval = -$4;
|
||||||
}
|
}
|
||||||
| '$' '-' LFCONST
|
| '$' '-' LFCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = -$3;
|
$$.U.Dval = -$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,77 +491,85 @@ omem:
|
|||||||
con
|
con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_INDIR+x86.D_NONE;
|
$$.Type = obj.TYPE_MEM
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
| con '(' LLREG ')'
|
| con '(' LLREG ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+$3);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($3)
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
| con '(' LSP ')'
|
| con '(' LSP ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+x86.D_SP);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = x86.REG_SP
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
| con '(' LSREG ')'
|
| con '(' LSREG ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+$3);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($3)
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
| con '(' LLREG '*' con ')'
|
| con '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+x86.D_NONE);
|
$$.Type = obj.TYPE_MEM
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
$$.Index = uint8($3);
|
$$.Index = int16($3);
|
||||||
$$.Scale = int8($5);
|
$$.Scale = int8($5);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
| con '(' LLREG ')' '(' LLREG '*' con ')'
|
| con '(' LLREG ')' '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+$3);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($3)
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
$$.Index = uint8($6);
|
$$.Index = int16($6);
|
||||||
$$.Scale = int8($8);
|
$$.Scale = int8($8);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
| con '(' LLREG ')' '(' LSREG '*' con ')'
|
| con '(' LLREG ')' '(' LSREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+$3);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($3)
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
$$.Index = uint8($6);
|
$$.Index = int16($6);
|
||||||
$$.Scale = int8($8);
|
$$.Scale = int8($8);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
| '(' LLREG ')'
|
| '(' LLREG ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+$2);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($2)
|
||||||
}
|
}
|
||||||
| '(' LSP ')'
|
| '(' LSP ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+x86.D_SP);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = x86.REG_SP
|
||||||
}
|
}
|
||||||
| '(' LLREG '*' con ')'
|
| '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+x86.D_NONE);
|
$$.Type = obj.TYPE_MEM
|
||||||
$$.Index = uint8($2);
|
$$.Index = int16($2);
|
||||||
$$.Scale = int8($4);
|
$$.Scale = int8($4);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
| '(' LLREG ')' '(' LLREG '*' con ')'
|
| '(' LLREG ')' '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(x86.D_INDIR+$2);
|
$$.Type = obj.TYPE_MEM
|
||||||
$$.Index = uint8($5);
|
$$.Reg = int16($2)
|
||||||
|
$$.Index = int16($5);
|
||||||
$$.Scale = int8($7);
|
$$.Scale = int8($7);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
@ -566,7 +582,7 @@ nmem:
|
|||||||
| nam '(' LLREG '*' con ')'
|
| nam '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.Index = uint8($3);
|
$$.Index = int16($3);
|
||||||
$$.Scale = int8($5);
|
$$.Scale = int8($5);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
@ -575,14 +591,16 @@ nam:
|
|||||||
LNAME offset '(' pointer ')'
|
LNAME offset '(' pointer ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($4);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Name = int8($4)
|
||||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||||
$$.Offset = $2;
|
$$.Offset = $2;
|
||||||
}
|
}
|
||||||
| LNAME '<' '>' offset '(' LSB ')'
|
| LNAME '<' '>' offset '(' LSB ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = x86.D_STATIC;
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Name = obj.NAME_STATIC
|
||||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
||||||
$$.Offset = $4;
|
$$.Offset = $4;
|
||||||
}
|
}
|
||||||
@ -604,7 +622,7 @@ pointer:
|
|||||||
LSB
|
LSB
|
||||||
| LSP
|
| LSP
|
||||||
{
|
{
|
||||||
$$ = x86.D_AUTO;
|
$$ = obj.NAME_AUTO;
|
||||||
}
|
}
|
||||||
| LFP
|
| LFP
|
||||||
|
|
||||||
@ -631,22 +649,34 @@ con:
|
|||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
con2:
|
textsize:
|
||||||
LCONST
|
LCONST
|
||||||
{
|
{
|
||||||
$$ = int64(uint64($1 & 0xffffffff) + (obj.ArgsSizeUnknown<<32))
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = $1;
|
||||||
|
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||||
}
|
}
|
||||||
| '-' LCONST
|
| '-' LCONST
|
||||||
{
|
{
|
||||||
$$ = int64(uint64(-$2 & 0xffffffff) + (obj.ArgsSizeUnknown<<32))
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = -$2;
|
||||||
|
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||||
}
|
}
|
||||||
| LCONST '-' LCONST
|
| LCONST '-' LCONST
|
||||||
{
|
{
|
||||||
$$ = ($1 & 0xffffffff) + (($3 & 0xffff) << 32);
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = $1;
|
||||||
|
$$.U.Argsize = int32($3);
|
||||||
}
|
}
|
||||||
| '-' LCONST '-' LCONST
|
| '-' LCONST '-' LCONST
|
||||||
{
|
{
|
||||||
$$ = (-$2 & 0xffffffff) + (($4 & 0xffff) << 32);
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = -$2;
|
||||||
|
$$.U.Argsize = int32($4);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr:
|
expr:
|
||||||
|
@ -89,124 +89,125 @@ func yyparse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lexinit = []asm.Lextab{
|
var lexinit = []asm.Lextab{
|
||||||
{"SP", LSP, x86.D_AUTO},
|
{"SP", LSP, obj.NAME_AUTO},
|
||||||
{"SB", LSB, x86.D_EXTERN},
|
{"SB", LSB, obj.NAME_EXTERN},
|
||||||
{"FP", LFP, x86.D_PARAM},
|
{"FP", LFP, obj.NAME_PARAM},
|
||||||
{"PC", LPC, x86.D_BRANCH},
|
{"PC", LPC, obj.TYPE_BRANCH},
|
||||||
{"AL", LBREG, x86.D_AL},
|
|
||||||
{"CL", LBREG, x86.D_CL},
|
|
||||||
{"DL", LBREG, x86.D_DL},
|
|
||||||
{"BL", LBREG, x86.D_BL},
|
|
||||||
/* "SPB", LBREG, D_SPB, */
|
|
||||||
{"SIB", LBREG, x86.D_SIB},
|
|
||||||
{"DIB", LBREG, x86.D_DIB},
|
|
||||||
{"BPB", LBREG, x86.D_BPB},
|
|
||||||
{"R8B", LBREG, x86.D_R8B},
|
|
||||||
{"R9B", LBREG, x86.D_R9B},
|
|
||||||
{"R10B", LBREG, x86.D_R10B},
|
|
||||||
{"R11B", LBREG, x86.D_R11B},
|
|
||||||
{"R12B", LBREG, x86.D_R12B},
|
|
||||||
{"R13B", LBREG, x86.D_R13B},
|
|
||||||
{"R14B", LBREG, x86.D_R14B},
|
|
||||||
{"R15B", LBREG, x86.D_R15B},
|
|
||||||
{"AH", LBREG, x86.D_AH},
|
|
||||||
{"CH", LBREG, x86.D_CH},
|
|
||||||
{"DH", LBREG, x86.D_DH},
|
|
||||||
{"BH", LBREG, x86.D_BH},
|
|
||||||
{"AX", LLREG, x86.D_AX},
|
|
||||||
{"CX", LLREG, x86.D_CX},
|
|
||||||
{"DX", LLREG, x86.D_DX},
|
|
||||||
{"BX", LLREG, x86.D_BX},
|
|
||||||
|
|
||||||
/* "SP", LLREG, D_SP, */
|
{"AL", LBREG, x86.REG_AL},
|
||||||
{"BP", LLREG, x86.D_BP},
|
{"CL", LBREG, x86.REG_CL},
|
||||||
{"SI", LLREG, x86.D_SI},
|
{"DL", LBREG, x86.REG_DL},
|
||||||
{"DI", LLREG, x86.D_DI},
|
{"BL", LBREG, x86.REG_BL},
|
||||||
{"R8", LLREG, x86.D_R8},
|
/* "SPB", LBREG, REG_SPB, */
|
||||||
{"R9", LLREG, x86.D_R9},
|
{"SIB", LBREG, x86.REG_SIB},
|
||||||
{"R10", LLREG, x86.D_R10},
|
{"DIB", LBREG, x86.REG_DIB},
|
||||||
{"R11", LLREG, x86.D_R11},
|
{"BPB", LBREG, x86.REG_BPB},
|
||||||
{"R12", LLREG, x86.D_R12},
|
{"R8B", LBREG, x86.REG_R8B},
|
||||||
{"R13", LLREG, x86.D_R13},
|
{"R9B", LBREG, x86.REG_R9B},
|
||||||
{"R14", LLREG, x86.D_R14},
|
{"R10B", LBREG, x86.REG_R10B},
|
||||||
{"R15", LLREG, x86.D_R15},
|
{"R11B", LBREG, x86.REG_R11B},
|
||||||
|
{"R12B", LBREG, x86.REG_R12B},
|
||||||
|
{"R13B", LBREG, x86.REG_R13B},
|
||||||
|
{"R14B", LBREG, x86.REG_R14B},
|
||||||
|
{"R15B", LBREG, x86.REG_R15B},
|
||||||
|
{"AH", LBREG, x86.REG_AH},
|
||||||
|
{"CH", LBREG, x86.REG_CH},
|
||||||
|
{"DH", LBREG, x86.REG_DH},
|
||||||
|
{"BH", LBREG, x86.REG_BH},
|
||||||
|
{"AX", LLREG, x86.REG_AX},
|
||||||
|
{"CX", LLREG, x86.REG_CX},
|
||||||
|
{"DX", LLREG, x86.REG_DX},
|
||||||
|
{"BX", LLREG, x86.REG_BX},
|
||||||
|
|
||||||
|
/* "SP", LLREG, REG_SP, */
|
||||||
|
{"BP", LLREG, x86.REG_BP},
|
||||||
|
{"SI", LLREG, x86.REG_SI},
|
||||||
|
{"DI", LLREG, x86.REG_DI},
|
||||||
|
{"R8", LLREG, x86.REG_R8},
|
||||||
|
{"R9", LLREG, x86.REG_R9},
|
||||||
|
{"R10", LLREG, x86.REG_R10},
|
||||||
|
{"R11", LLREG, x86.REG_R11},
|
||||||
|
{"R12", LLREG, x86.REG_R12},
|
||||||
|
{"R13", LLREG, x86.REG_R13},
|
||||||
|
{"R14", LLREG, x86.REG_R14},
|
||||||
|
{"R15", LLREG, x86.REG_R15},
|
||||||
{"RARG", LLREG, x86.REGARG},
|
{"RARG", LLREG, x86.REGARG},
|
||||||
{"F0", LFREG, x86.D_F0 + 0},
|
{"F0", LFREG, x86.REG_F0 + 0},
|
||||||
{"F1", LFREG, x86.D_F0 + 1},
|
{"F1", LFREG, x86.REG_F0 + 1},
|
||||||
{"F2", LFREG, x86.D_F0 + 2},
|
{"F2", LFREG, x86.REG_F0 + 2},
|
||||||
{"F3", LFREG, x86.D_F0 + 3},
|
{"F3", LFREG, x86.REG_F0 + 3},
|
||||||
{"F4", LFREG, x86.D_F0 + 4},
|
{"F4", LFREG, x86.REG_F0 + 4},
|
||||||
{"F5", LFREG, x86.D_F0 + 5},
|
{"F5", LFREG, x86.REG_F0 + 5},
|
||||||
{"F6", LFREG, x86.D_F0 + 6},
|
{"F6", LFREG, x86.REG_F0 + 6},
|
||||||
{"F7", LFREG, x86.D_F0 + 7},
|
{"F7", LFREG, x86.REG_F0 + 7},
|
||||||
{"M0", LMREG, x86.D_M0 + 0},
|
{"M0", LMREG, x86.REG_M0 + 0},
|
||||||
{"M1", LMREG, x86.D_M0 + 1},
|
{"M1", LMREG, x86.REG_M0 + 1},
|
||||||
{"M2", LMREG, x86.D_M0 + 2},
|
{"M2", LMREG, x86.REG_M0 + 2},
|
||||||
{"M3", LMREG, x86.D_M0 + 3},
|
{"M3", LMREG, x86.REG_M0 + 3},
|
||||||
{"M4", LMREG, x86.D_M0 + 4},
|
{"M4", LMREG, x86.REG_M0 + 4},
|
||||||
{"M5", LMREG, x86.D_M0 + 5},
|
{"M5", LMREG, x86.REG_M0 + 5},
|
||||||
{"M6", LMREG, x86.D_M0 + 6},
|
{"M6", LMREG, x86.REG_M0 + 6},
|
||||||
{"M7", LMREG, x86.D_M0 + 7},
|
{"M7", LMREG, x86.REG_M0 + 7},
|
||||||
{"X0", LXREG, x86.D_X0 + 0},
|
{"X0", LXREG, x86.REG_X0 + 0},
|
||||||
{"X1", LXREG, x86.D_X0 + 1},
|
{"X1", LXREG, x86.REG_X0 + 1},
|
||||||
{"X2", LXREG, x86.D_X0 + 2},
|
{"X2", LXREG, x86.REG_X0 + 2},
|
||||||
{"X3", LXREG, x86.D_X0 + 3},
|
{"X3", LXREG, x86.REG_X0 + 3},
|
||||||
{"X4", LXREG, x86.D_X0 + 4},
|
{"X4", LXREG, x86.REG_X0 + 4},
|
||||||
{"X5", LXREG, x86.D_X0 + 5},
|
{"X5", LXREG, x86.REG_X0 + 5},
|
||||||
{"X6", LXREG, x86.D_X0 + 6},
|
{"X6", LXREG, x86.REG_X0 + 6},
|
||||||
{"X7", LXREG, x86.D_X0 + 7},
|
{"X7", LXREG, x86.REG_X0 + 7},
|
||||||
{"X8", LXREG, x86.D_X0 + 8},
|
{"X8", LXREG, x86.REG_X0 + 8},
|
||||||
{"X9", LXREG, x86.D_X0 + 9},
|
{"X9", LXREG, x86.REG_X0 + 9},
|
||||||
{"X10", LXREG, x86.D_X0 + 10},
|
{"X10", LXREG, x86.REG_X0 + 10},
|
||||||
{"X11", LXREG, x86.D_X0 + 11},
|
{"X11", LXREG, x86.REG_X0 + 11},
|
||||||
{"X12", LXREG, x86.D_X0 + 12},
|
{"X12", LXREG, x86.REG_X0 + 12},
|
||||||
{"X13", LXREG, x86.D_X0 + 13},
|
{"X13", LXREG, x86.REG_X0 + 13},
|
||||||
{"X14", LXREG, x86.D_X0 + 14},
|
{"X14", LXREG, x86.REG_X0 + 14},
|
||||||
{"X15", LXREG, x86.D_X0 + 15},
|
{"X15", LXREG, x86.REG_X0 + 15},
|
||||||
{"CS", LSREG, x86.D_CS},
|
{"CS", LSREG, x86.REG_CS},
|
||||||
{"SS", LSREG, x86.D_SS},
|
{"SS", LSREG, x86.REG_SS},
|
||||||
{"DS", LSREG, x86.D_DS},
|
{"DS", LSREG, x86.REG_DS},
|
||||||
{"ES", LSREG, x86.D_ES},
|
{"ES", LSREG, x86.REG_ES},
|
||||||
{"FS", LSREG, x86.D_FS},
|
{"FS", LSREG, x86.REG_FS},
|
||||||
{"GS", LSREG, x86.D_GS},
|
{"GS", LSREG, x86.REG_GS},
|
||||||
{"GDTR", LBREG, x86.D_GDTR},
|
{"GDTR", LBREG, x86.REG_GDTR},
|
||||||
{"IDTR", LBREG, x86.D_IDTR},
|
{"IDTR", LBREG, x86.REG_IDTR},
|
||||||
{"LDTR", LBREG, x86.D_LDTR},
|
{"LDTR", LBREG, x86.REG_LDTR},
|
||||||
{"MSW", LBREG, x86.D_MSW},
|
{"MSW", LBREG, x86.REG_MSW},
|
||||||
{"TASK", LBREG, x86.D_TASK},
|
{"TASK", LBREG, x86.REG_TASK},
|
||||||
{"CR0", LBREG, x86.D_CR + 0},
|
{"CR0", LBREG, x86.REG_CR + 0},
|
||||||
{"CR1", LBREG, x86.D_CR + 1},
|
{"CR1", LBREG, x86.REG_CR + 1},
|
||||||
{"CR2", LBREG, x86.D_CR + 2},
|
{"CR2", LBREG, x86.REG_CR + 2},
|
||||||
{"CR3", LBREG, x86.D_CR + 3},
|
{"CR3", LBREG, x86.REG_CR + 3},
|
||||||
{"CR4", LBREG, x86.D_CR + 4},
|
{"CR4", LBREG, x86.REG_CR + 4},
|
||||||
{"CR5", LBREG, x86.D_CR + 5},
|
{"CR5", LBREG, x86.REG_CR + 5},
|
||||||
{"CR6", LBREG, x86.D_CR + 6},
|
{"CR6", LBREG, x86.REG_CR + 6},
|
||||||
{"CR7", LBREG, x86.D_CR + 7},
|
{"CR7", LBREG, x86.REG_CR + 7},
|
||||||
{"CR8", LBREG, x86.D_CR + 8},
|
{"CR8", LBREG, x86.REG_CR + 8},
|
||||||
{"CR9", LBREG, x86.D_CR + 9},
|
{"CR9", LBREG, x86.REG_CR + 9},
|
||||||
{"CR10", LBREG, x86.D_CR + 10},
|
{"CR10", LBREG, x86.REG_CR + 10},
|
||||||
{"CR11", LBREG, x86.D_CR + 11},
|
{"CR11", LBREG, x86.REG_CR + 11},
|
||||||
{"CR12", LBREG, x86.D_CR + 12},
|
{"CR12", LBREG, x86.REG_CR + 12},
|
||||||
{"CR13", LBREG, x86.D_CR + 13},
|
{"CR13", LBREG, x86.REG_CR + 13},
|
||||||
{"CR14", LBREG, x86.D_CR + 14},
|
{"CR14", LBREG, x86.REG_CR + 14},
|
||||||
{"CR15", LBREG, x86.D_CR + 15},
|
{"CR15", LBREG, x86.REG_CR + 15},
|
||||||
{"DR0", LBREG, x86.D_DR + 0},
|
{"DR0", LBREG, x86.REG_DR + 0},
|
||||||
{"DR1", LBREG, x86.D_DR + 1},
|
{"DR1", LBREG, x86.REG_DR + 1},
|
||||||
{"DR2", LBREG, x86.D_DR + 2},
|
{"DR2", LBREG, x86.REG_DR + 2},
|
||||||
{"DR3", LBREG, x86.D_DR + 3},
|
{"DR3", LBREG, x86.REG_DR + 3},
|
||||||
{"DR4", LBREG, x86.D_DR + 4},
|
{"DR4", LBREG, x86.REG_DR + 4},
|
||||||
{"DR5", LBREG, x86.D_DR + 5},
|
{"DR5", LBREG, x86.REG_DR + 5},
|
||||||
{"DR6", LBREG, x86.D_DR + 6},
|
{"DR6", LBREG, x86.REG_DR + 6},
|
||||||
{"DR7", LBREG, x86.D_DR + 7},
|
{"DR7", LBREG, x86.REG_DR + 7},
|
||||||
{"TR0", LBREG, x86.D_TR + 0},
|
{"TR0", LBREG, x86.REG_TR + 0},
|
||||||
{"TR1", LBREG, x86.D_TR + 1},
|
{"TR1", LBREG, x86.REG_TR + 1},
|
||||||
{"TR2", LBREG, x86.D_TR + 2},
|
{"TR2", LBREG, x86.REG_TR + 2},
|
||||||
{"TR3", LBREG, x86.D_TR + 3},
|
{"TR3", LBREG, x86.REG_TR + 3},
|
||||||
{"TR4", LBREG, x86.D_TR + 4},
|
{"TR4", LBREG, x86.REG_TR + 4},
|
||||||
{"TR5", LBREG, x86.D_TR + 5},
|
{"TR5", LBREG, x86.REG_TR + 5},
|
||||||
{"TR6", LBREG, x86.D_TR + 6},
|
{"TR6", LBREG, x86.REG_TR + 6},
|
||||||
{"TR7", LBREG, x86.D_TR + 7},
|
{"TR7", LBREG, x86.REG_TR + 7},
|
||||||
{"TLS", LSREG, x86.D_TLS},
|
{"TLS", LSREG, x86.REG_TLS},
|
||||||
{"AAA", LTYPE0, x86.AAAA},
|
{"AAA", LTYPE0, x86.AAAA},
|
||||||
{"AAD", LTYPE0, x86.AAAD},
|
{"AAD", LTYPE0, x86.AAAD},
|
||||||
{"AAM", LTYPE0, x86.AAAM},
|
{"AAM", LTYPE0, x86.AAAM},
|
||||||
@ -248,7 +249,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"BTSW", LTYPE3, x86.ABTSW},
|
{"BTSW", LTYPE3, x86.ABTSW},
|
||||||
{"BTW", LTYPE3, x86.ABTW},
|
{"BTW", LTYPE3, x86.ABTW},
|
||||||
{"BYTE", LTYPE2, x86.ABYTE},
|
{"BYTE", LTYPE2, x86.ABYTE},
|
||||||
{"CALL", LTYPEC, x86.ACALL},
|
{"CALL", LTYPEC, obj.ACALL},
|
||||||
{"CLC", LTYPE0, x86.ACLC},
|
{"CLC", LTYPE0, x86.ACLC},
|
||||||
{"CLD", LTYPE0, x86.ACLD},
|
{"CLD", LTYPE0, x86.ACLD},
|
||||||
{"CLI", LTYPE0, x86.ACLI},
|
{"CLI", LTYPE0, x86.ACLI},
|
||||||
@ -270,7 +271,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"CPUID", LTYPE0, x86.ACPUID},
|
{"CPUID", LTYPE0, x86.ACPUID},
|
||||||
{"DAA", LTYPE0, x86.ADAA},
|
{"DAA", LTYPE0, x86.ADAA},
|
||||||
{"DAS", LTYPE0, x86.ADAS},
|
{"DAS", LTYPE0, x86.ADAS},
|
||||||
{"DATA", LTYPED, x86.ADATA},
|
{"DATA", LTYPED, obj.ADATA},
|
||||||
{"DECB", LTYPE1, x86.ADECB},
|
{"DECB", LTYPE1, x86.ADECB},
|
||||||
{"DECL", LTYPE1, x86.ADECL},
|
{"DECL", LTYPE1, x86.ADECL},
|
||||||
{"DECQ", LTYPE1, x86.ADECQ},
|
{"DECQ", LTYPE1, x86.ADECQ},
|
||||||
@ -280,9 +281,9 @@ var lexinit = []asm.Lextab{
|
|||||||
{"DIVQ", LTYPE2, x86.ADIVQ},
|
{"DIVQ", LTYPE2, x86.ADIVQ},
|
||||||
{"DIVW", LTYPE2, x86.ADIVW},
|
{"DIVW", LTYPE2, x86.ADIVW},
|
||||||
{"EMMS", LTYPE0, x86.AEMMS},
|
{"EMMS", LTYPE0, x86.AEMMS},
|
||||||
{"END", LTYPE0, x86.AEND},
|
{"END", LTYPE0, obj.AEND},
|
||||||
{"ENTER", LTYPE2, x86.AENTER},
|
{"ENTER", LTYPE2, x86.AENTER},
|
||||||
{"GLOBL", LTYPEG, x86.AGLOBL},
|
{"GLOBL", LTYPEG, obj.AGLOBL},
|
||||||
{"HLT", LTYPE0, x86.AHLT},
|
{"HLT", LTYPE0, x86.AHLT},
|
||||||
{"IDIVB", LTYPE2, x86.AIDIVB},
|
{"IDIVB", LTYPE2, x86.AIDIVB},
|
||||||
{"IDIVL", LTYPE2, x86.AIDIVL},
|
{"IDIVL", LTYPE2, x86.AIDIVL},
|
||||||
@ -357,7 +358,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"JNLE", LTYPER, x86.AJGT}, /* alternate */
|
{"JNLE", LTYPER, x86.AJGT}, /* alternate */
|
||||||
{"JCXZL", LTYPER, x86.AJCXZL},
|
{"JCXZL", LTYPER, x86.AJCXZL},
|
||||||
{"JCXZQ", LTYPER, x86.AJCXZQ},
|
{"JCXZQ", LTYPER, x86.AJCXZQ},
|
||||||
{"JMP", LTYPEC, x86.AJMP},
|
{"JMP", LTYPEC, obj.AJMP},
|
||||||
{"LAHF", LTYPE0, x86.ALAHF},
|
{"LAHF", LTYPE0, x86.ALAHF},
|
||||||
{"LARL", LTYPE3, x86.ALARL},
|
{"LARL", LTYPE3, x86.ALARL},
|
||||||
{"LARW", LTYPE3, x86.ALARW},
|
{"LARW", LTYPE3, x86.ALARW},
|
||||||
@ -412,7 +413,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"NEGL", LTYPE1, x86.ANEGL},
|
{"NEGL", LTYPE1, x86.ANEGL},
|
||||||
{"NEGQ", LTYPE1, x86.ANEGQ},
|
{"NEGQ", LTYPE1, x86.ANEGQ},
|
||||||
{"NEGW", LTYPE1, x86.ANEGW},
|
{"NEGW", LTYPE1, x86.ANEGW},
|
||||||
{"NOP", LTYPEN, x86.ANOP},
|
{"NOP", LTYPEN, obj.ANOP},
|
||||||
{"NOTB", LTYPE1, x86.ANOTB},
|
{"NOTB", LTYPE1, x86.ANOTB},
|
||||||
{"NOTL", LTYPE1, x86.ANOTL},
|
{"NOTL", LTYPE1, x86.ANOTL},
|
||||||
{"NOTQ", LTYPE1, x86.ANOTQ},
|
{"NOTQ", LTYPE1, x86.ANOTQ},
|
||||||
@ -457,7 +458,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"RDTSC", LTYPE0, x86.ARDTSC},
|
{"RDTSC", LTYPE0, x86.ARDTSC},
|
||||||
{"REP", LTYPE0, x86.AREP},
|
{"REP", LTYPE0, x86.AREP},
|
||||||
{"REPN", LTYPE0, x86.AREPN},
|
{"REPN", LTYPE0, x86.AREPN},
|
||||||
{"RET", LTYPE0, x86.ARET},
|
{"RET", LTYPE0, obj.ARET},
|
||||||
{"RETFL", LTYPERT, x86.ARETFL},
|
{"RETFL", LTYPERT, x86.ARETFL},
|
||||||
{"RETFW", LTYPERT, x86.ARETFW},
|
{"RETFW", LTYPERT, x86.ARETFW},
|
||||||
{"RETFQ", LTYPERT, x86.ARETFQ},
|
{"RETFQ", LTYPERT, x86.ARETFQ},
|
||||||
@ -533,7 +534,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"TESTL", LTYPE3, x86.ATESTL},
|
{"TESTL", LTYPE3, x86.ATESTL},
|
||||||
{"TESTQ", LTYPE3, x86.ATESTQ},
|
{"TESTQ", LTYPE3, x86.ATESTQ},
|
||||||
{"TESTW", LTYPE3, x86.ATESTW},
|
{"TESTW", LTYPE3, x86.ATESTW},
|
||||||
{"TEXT", LTYPET, x86.ATEXT},
|
{"TEXT", LTYPET, obj.ATEXT},
|
||||||
{"VERR", LTYPE2, x86.AVERR},
|
{"VERR", LTYPE2, x86.AVERR},
|
||||||
{"VERW", LTYPE2, x86.AVERW},
|
{"VERW", LTYPE2, x86.AVERW},
|
||||||
{"QUAD", LTYPE2, x86.AQUAD},
|
{"QUAD", LTYPE2, x86.AQUAD},
|
||||||
@ -900,7 +901,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"PREFETCHT1", LTYPE2, x86.APREFETCHT1},
|
{"PREFETCHT1", LTYPE2, x86.APREFETCHT1},
|
||||||
{"PREFETCHT2", LTYPE2, x86.APREFETCHT2},
|
{"PREFETCHT2", LTYPE2, x86.APREFETCHT2},
|
||||||
{"PREFETCHNTA", LTYPE2, x86.APREFETCHNTA},
|
{"PREFETCHNTA", LTYPE2, x86.APREFETCHNTA},
|
||||||
{"UNDEF", LTYPE0, x86.AUNDEF},
|
{"UNDEF", LTYPE0, obj.AUNDEF},
|
||||||
{"AESENC", LTYPE3, x86.AAESENC},
|
{"AESENC", LTYPE3, x86.AAESENC},
|
||||||
{"AESENCLAST", LTYPE3, x86.AAESENCLAST},
|
{"AESENCLAST", LTYPE3, x86.AAESENCLAST},
|
||||||
{"AESDEC", LTYPE3, x86.AAESDEC},
|
{"AESDEC", LTYPE3, x86.AAESDEC},
|
||||||
@ -908,15 +909,13 @@ var lexinit = []asm.Lextab{
|
|||||||
{"AESIMC", LTYPE3, x86.AAESIMC},
|
{"AESIMC", LTYPE3, x86.AAESIMC},
|
||||||
{"AESKEYGENASSIST", LTYPEX, x86.AAESKEYGENASSIST},
|
{"AESKEYGENASSIST", LTYPEX, x86.AAESKEYGENASSIST},
|
||||||
{"PSHUFD", LTYPEX, x86.APSHUFD},
|
{"PSHUFD", LTYPEX, x86.APSHUFD},
|
||||||
{"USEFIELD", LTYPEN, x86.AUSEFIELD},
|
{"USEFIELD", LTYPEN, obj.AUSEFIELD},
|
||||||
{"PCLMULQDQ", LTYPEX, x86.APCLMULQDQ},
|
{"PCLMULQDQ", LTYPEX, x86.APCLMULQDQ},
|
||||||
{"PCDATA", LTYPEPC, x86.APCDATA},
|
{"PCDATA", LTYPEPC, obj.APCDATA},
|
||||||
{"FUNCDATA", LTYPEF, x86.AFUNCDATA},
|
{"FUNCDATA", LTYPEF, obj.AFUNCDATA},
|
||||||
}
|
}
|
||||||
|
|
||||||
func cinit() {
|
func cinit() {
|
||||||
nullgen.Type = x86.D_NONE
|
|
||||||
nullgen.Index = x86.D_NONE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkscale(scale int8) {
|
func checkscale(scale int8) {
|
||||||
@ -936,7 +935,7 @@ func cclean() {
|
|||||||
|
|
||||||
g2.from = nullgen
|
g2.from = nullgen
|
||||||
g2.to = nullgen
|
g2.to = nullgen
|
||||||
outcode(x86.AEND, &g2)
|
outcode(obj.AEND, &g2)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastpc *obj.Prog
|
var lastpc *obj.Prog
|
||||||
@ -973,7 +972,7 @@ func outcode(a int, g2 *Addr2) {
|
|||||||
lastpc = p
|
lastpc = p
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if a != x86.AGLOBL && a != x86.ADATA {
|
if a != obj.AGLOBL && a != obj.ADATA {
|
||||||
asm.PC++
|
asm.PC++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -65,10 +65,9 @@ import (
|
|||||||
%token <sval> LSCONST LSP
|
%token <sval> LSCONST LSP
|
||||||
%token <sym> LNAME LLAB LVAR
|
%token <sym> LNAME LLAB LVAR
|
||||||
%type <lval> con expr pointer offset
|
%type <lval> con expr pointer offset
|
||||||
%type <con2> con2
|
%type <addr> mem imm reg nam rel rem rim rom omem nmem textsize
|
||||||
%type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
|
|
||||||
%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
|
%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
|
||||||
%type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
|
%type <addr2> spec3 spec4 spec5 spec6 spec7 spec9 spec10 spec11 spec12
|
||||||
%%
|
%%
|
||||||
prog:
|
prog:
|
||||||
| prog
|
| prog
|
||||||
@ -111,14 +110,14 @@ inst:
|
|||||||
| LTYPE3 rimrem { outcode(int($1), &$2); }
|
| LTYPE3 rimrem { outcode(int($1), &$2); }
|
||||||
| LTYPE4 remrim { outcode(int($1), &$2); }
|
| LTYPE4 remrim { outcode(int($1), &$2); }
|
||||||
| LTYPER nonrel { outcode(int($1), &$2); }
|
| LTYPER nonrel { outcode(int($1), &$2); }
|
||||||
| LTYPED spec1 { outcode(int($1), &$2); }
|
| spec1
|
||||||
| LTYPET spec2 { outcode(int($1), &$2); }
|
| spec2
|
||||||
| LTYPEC spec3 { outcode(int($1), &$2); }
|
| LTYPEC spec3 { outcode(int($1), &$2); }
|
||||||
| LTYPEN spec4 { outcode(int($1), &$2); }
|
| LTYPEN spec4 { outcode(int($1), &$2); }
|
||||||
| LTYPES spec5 { outcode(int($1), &$2); }
|
| LTYPES spec5 { outcode(int($1), &$2); }
|
||||||
| LTYPEM spec6 { outcode(int($1), &$2); }
|
| LTYPEM spec6 { outcode(int($1), &$2); }
|
||||||
| LTYPEI spec7 { outcode(int($1), &$2); }
|
| LTYPEI spec7 { outcode(int($1), &$2); }
|
||||||
| LTYPEG spec8 { outcode(int($1), &$2); }
|
| spec8
|
||||||
| LTYPEXC spec9 { outcode(int($1), &$2); }
|
| LTYPEXC spec9 { outcode(int($1), &$2); }
|
||||||
| LTYPEX spec10 { outcode(int($1), &$2); }
|
| LTYPEX spec10 { outcode(int($1), &$2); }
|
||||||
| LTYPEPC spec11 { outcode(int($1), &$2); }
|
| LTYPEPC spec11 { outcode(int($1), &$2); }
|
||||||
@ -191,28 +190,48 @@ nonrel:
|
|||||||
}
|
}
|
||||||
|
|
||||||
spec1: /* DATA */
|
spec1: /* DATA */
|
||||||
nam '/' con ',' imm
|
LTYPED nam '/' con ',' imm
|
||||||
{
|
{
|
||||||
$$.from = $1;
|
outcode(obj.ADATA, &Addr2{$2, $6})
|
||||||
$$.from.Scale = int8($3);
|
if asm.Pass > 1 {
|
||||||
$$.to = $5;
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spec2: /* TEXT */
|
spec2: /* TEXT */
|
||||||
mem ',' imm2
|
LTYPET mem ',' '$' textsize
|
||||||
{
|
{
|
||||||
asm.Settext($1.Sym);
|
asm.Settext($2.Sym);
|
||||||
$$.from = $1;
|
outcode(obj.ATEXT, &Addr2{$2, $5})
|
||||||
$$.to = $3;
|
|
||||||
}
|
}
|
||||||
| mem ',' con ',' imm2
|
| LTYPET mem ',' con ',' '$' textsize
|
||||||
{
|
{
|
||||||
asm.Settext($1.Sym);
|
asm.Settext($2.Sym);
|
||||||
$$.from = $1;
|
outcode(obj.ATEXT, &Addr2{$2, $7})
|
||||||
$$.from.Scale = int8($3);
|
if asm.Pass > 1 {
|
||||||
$$.to = $5;
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spec8: /* GLOBL */
|
||||||
|
LTYPEG mem ',' imm
|
||||||
|
{
|
||||||
|
asm.Settext($2.Sym);
|
||||||
|
outcode(obj.AGLOBL, &Addr2{$2, $4})
|
||||||
|
}
|
||||||
|
| LTYPEG mem ',' con ',' imm
|
||||||
|
{
|
||||||
|
asm.Settext($2.Sym);
|
||||||
|
outcode(obj.AGLOBL, &Addr2{$2, $6})
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
spec3: /* JMP/CALL */
|
spec3: /* JMP/CALL */
|
||||||
',' rom
|
',' rom
|
||||||
{
|
{
|
||||||
@ -228,8 +247,7 @@ spec3: /* JMP/CALL */
|
|||||||
{
|
{
|
||||||
$$.from = nullgen;
|
$$.from = nullgen;
|
||||||
$$.to = $2;
|
$$.to = $2;
|
||||||
$$.to.Index = uint8($2.Type)
|
$$.to.Type = obj.TYPE_INDIR
|
||||||
$$.to.Type = D_INDIR+D_ADDR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spec4: /* NOP */
|
spec4: /* NOP */
|
||||||
@ -246,10 +264,10 @@ spec5: /* SHL/SHR */
|
|||||||
{
|
{
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
if $$.from.Index != D_NONE {
|
if $$.from.Index != obj.TYPE_NONE {
|
||||||
yyerror("dp shift with lhs index");
|
yyerror("dp shift with lhs index");
|
||||||
}
|
}
|
||||||
$$.from.Index = uint8($5);
|
$$.from.Index = int16($5);
|
||||||
}
|
}
|
||||||
|
|
||||||
spec6: /* MOVW/MOVL */
|
spec6: /* MOVW/MOVL */
|
||||||
@ -262,10 +280,10 @@ spec6: /* MOVW/MOVL */
|
|||||||
{
|
{
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
if $$.to.Index != D_NONE {
|
if $$.to.Index != obj.TYPE_NONE {
|
||||||
yyerror("dp move with lhs index");
|
yyerror("dp move with lhs index");
|
||||||
}
|
}
|
||||||
$$.to.Index = uint8($5);
|
$$.to.Index = int16($5);
|
||||||
}
|
}
|
||||||
|
|
||||||
spec7:
|
spec7:
|
||||||
@ -285,19 +303,6 @@ spec7:
|
|||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
}
|
}
|
||||||
|
|
||||||
spec8: /* GLOBL */
|
|
||||||
mem ',' imm
|
|
||||||
{
|
|
||||||
$$.from = $1;
|
|
||||||
$$.to = $3;
|
|
||||||
}
|
|
||||||
| mem ',' con ',' imm
|
|
||||||
{
|
|
||||||
$$.from = $1;
|
|
||||||
$$.from.Scale = int8($3);
|
|
||||||
$$.to = $5;
|
|
||||||
}
|
|
||||||
|
|
||||||
spec9: /* CMPPS/CMPPD */
|
spec9: /* CMPPS/CMPPD */
|
||||||
reg ',' rem ',' con
|
reg ',' rem ',' con
|
||||||
{
|
{
|
||||||
@ -311,7 +316,7 @@ spec10: /* PINSRD */
|
|||||||
{
|
{
|
||||||
$$.from = $3;
|
$$.from = $3;
|
||||||
$$.to = $5;
|
$$.to = $5;
|
||||||
if $1.Type != D_CONST {
|
if $1.Type != obj.TYPE_CONST {
|
||||||
yyerror("illegal constant")
|
yyerror("illegal constant")
|
||||||
}
|
}
|
||||||
$$.to.Offset = $1.Offset;
|
$$.to.Offset = $1.Offset;
|
||||||
@ -320,7 +325,7 @@ spec10: /* PINSRD */
|
|||||||
spec11: /* PCDATA */
|
spec11: /* PCDATA */
|
||||||
rim ',' rim
|
rim ',' rim
|
||||||
{
|
{
|
||||||
if $1.Type != D_CONST || $3.Type != D_CONST {
|
if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
|
||||||
yyerror("arguments to PCDATA must be integer constants");
|
yyerror("arguments to PCDATA must be integer constants");
|
||||||
}
|
}
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
@ -330,10 +335,10 @@ spec11: /* PCDATA */
|
|||||||
spec12: /* FUNCDATA */
|
spec12: /* FUNCDATA */
|
||||||
rim ',' rim
|
rim ',' rim
|
||||||
{
|
{
|
||||||
if $1.Type != D_CONST {
|
if $1.Type != obj.TYPE_CONST {
|
||||||
yyerror("index for FUNCDATA must be integer constant");
|
yyerror("index for FUNCDATA must be integer constant");
|
||||||
}
|
}
|
||||||
if $3.Type != D_EXTERN && $3.Type != D_STATIC {
|
if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
|
||||||
yyerror("value for FUNCDATA must be symbol reference");
|
yyerror("value for FUNCDATA must be symbol reference");
|
||||||
}
|
}
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
@ -367,7 +372,7 @@ rel:
|
|||||||
con '(' LPC ')'
|
con '(' LPC ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_BRANCH;
|
$$.Type = obj.TYPE_BRANCH;
|
||||||
$$.Offset = $1 + int64(asm.PC);
|
$$.Offset = $1 + int64(asm.PC);
|
||||||
}
|
}
|
||||||
| LNAME offset
|
| LNAME offset
|
||||||
@ -377,7 +382,7 @@ rel:
|
|||||||
if asm.Pass == 2 && $1.Type != LLAB {
|
if asm.Pass == 2 && $1.Type != LLAB {
|
||||||
yyerror("undefined label: %s", $1.Labelname);
|
yyerror("undefined label: %s", $1.Labelname);
|
||||||
}
|
}
|
||||||
$$.Type = D_BRANCH;
|
$$.Type = obj.TYPE_BRANCH;
|
||||||
$$.Offset = $1.Value + $2;
|
$$.Offset = $1.Value + $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,46 +390,51 @@ reg:
|
|||||||
LBREG
|
LBREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LFREG
|
| LFREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LLREG
|
| LLREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LXREG
|
| LXREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LSP
|
| LSP
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SP;
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = REG_SP;
|
||||||
}
|
}
|
||||||
| LSREG
|
| LSREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
imm:
|
imm:
|
||||||
'$' con
|
'$' con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_CONST;
|
$$.Type = obj.TYPE_CONST;
|
||||||
$$.Offset = $2;
|
$$.Offset = $2;
|
||||||
}
|
}
|
||||||
| '$' nam
|
| '$' nam
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
$$.Index = uint8($2.Type);
|
$$.Type = obj.TYPE_ADDR
|
||||||
$$.Type = D_ADDR;
|
|
||||||
/*
|
/*
|
||||||
if($2.Type == D_AUTO || $2.Type == D_PARAM)
|
if($2.Type == D_AUTO || $2.Type == D_PARAM)
|
||||||
yyerror("constant cannot be automatic: %s",
|
yyerror("constant cannot be automatic: %s",
|
||||||
@ -434,65 +444,65 @@ imm:
|
|||||||
| '$' LSCONST
|
| '$' LSCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SCONST;
|
$$.Type = obj.TYPE_SCONST;
|
||||||
$$.U.Sval = $2
|
$$.U.Sval = $2
|
||||||
}
|
}
|
||||||
| '$' LFCONST
|
| '$' LFCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = $2;
|
$$.U.Dval = $2;
|
||||||
}
|
}
|
||||||
| '$' '(' LFCONST ')'
|
| '$' '(' LFCONST ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = $3;
|
$$.U.Dval = $3;
|
||||||
}
|
}
|
||||||
| '$' '(' '-' LFCONST ')'
|
| '$' '(' '-' LFCONST ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = -$4;
|
$$.U.Dval = -$4;
|
||||||
}
|
}
|
||||||
| '$' '-' LFCONST
|
| '$' '-' LFCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = -$3;
|
$$.U.Dval = -$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
imm2:
|
textsize:
|
||||||
'$' con2
|
|
||||||
{
|
|
||||||
$$ = nullgen;
|
|
||||||
$$.Type = D_CONST2;
|
|
||||||
$$.Offset = int64($2.v1);
|
|
||||||
$$.Offset2 = int32($2.v2);
|
|
||||||
}
|
|
||||||
|
|
||||||
con2:
|
|
||||||
LCONST
|
LCONST
|
||||||
{
|
{
|
||||||
$$.v1 = int32($1);
|
$$ = nullgen;
|
||||||
$$.v2 = -obj.ArgsSizeUnknown
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = $1;
|
||||||
|
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||||
}
|
}
|
||||||
| '-' LCONST
|
| '-' LCONST
|
||||||
{
|
{
|
||||||
$$.v1 = int32(-$2);
|
$$ = nullgen;
|
||||||
$$.v2 = -obj.ArgsSizeUnknown;
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = -$2;
|
||||||
|
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||||
}
|
}
|
||||||
| LCONST '-' LCONST
|
| LCONST '-' LCONST
|
||||||
{
|
{
|
||||||
$$.v1 = int32($1);
|
$$ = nullgen;
|
||||||
$$.v2 = int32($3);
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = $1;
|
||||||
|
$$.U.Argsize = int32($3);
|
||||||
}
|
}
|
||||||
| '-' LCONST '-' LCONST
|
| '-' LCONST '-' LCONST
|
||||||
{
|
{
|
||||||
$$.v1 = int32(-$2);
|
$$ = nullgen;
|
||||||
$$.v2 = int32($4);
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = -$2;
|
||||||
|
$$.U.Argsize = int32($4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mem:
|
mem:
|
||||||
omem
|
omem
|
||||||
| nmem
|
| nmem
|
||||||
@ -501,77 +511,85 @@ omem:
|
|||||||
con
|
con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_INDIR+D_NONE;
|
$$.Type = obj.TYPE_MEM
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
| con '(' LLREG ')'
|
| con '(' LLREG ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(D_INDIR+$3);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($3)
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
| con '(' LSP ')'
|
| con '(' LSP ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_INDIR+D_SP;
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = REG_SP
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
| con '(' LLREG '*' con ')'
|
| con '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_INDIR+D_NONE;
|
$$.Type = obj.TYPE_MEM
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
$$.Index = uint8($3);
|
$$.Index = int16($3);
|
||||||
$$.Scale = int8($5);
|
$$.Scale = int8($5);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
| con '(' LLREG ')' '(' LLREG '*' con ')'
|
| con '(' LLREG ')' '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(D_INDIR+$3);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($3)
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
$$.Index = uint8($6);
|
$$.Index = int16($6);
|
||||||
$$.Scale = int8($8);
|
$$.Scale = int8($8);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
| con '(' LLREG ')' '(' LSREG '*' con ')'
|
| con '(' LLREG ')' '(' LSREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(D_INDIR+$3);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($3)
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
$$.Index = uint8($6);
|
$$.Index = int16($6);
|
||||||
$$.Scale = int8($8);
|
$$.Scale = int8($8);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
| '(' LLREG ')'
|
| '(' LLREG ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(D_INDIR+$2);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($2);
|
||||||
}
|
}
|
||||||
| '(' LSP ')'
|
| '(' LSP ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_INDIR+D_SP;
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = REG_SP
|
||||||
}
|
}
|
||||||
| con '(' LSREG ')'
|
| con '(' LSREG ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(D_INDIR+$3);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Reg = int16($3)
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
| '(' LLREG '*' con ')'
|
| '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_INDIR+D_NONE;
|
$$.Type = obj.TYPE_MEM
|
||||||
$$.Index = uint8($2);
|
$$.Index = int16($2);
|
||||||
$$.Scale = int8($4);
|
$$.Scale = int8($4);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
| '(' LLREG ')' '(' LLREG '*' con ')'
|
| '(' LLREG ')' '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16(D_INDIR+$2);
|
$$.Type = obj.TYPE_MEM
|
||||||
$$.Index = uint8($5);
|
$$.Reg = int16($2)
|
||||||
|
$$.Index = int16($5);
|
||||||
$$.Scale = int8($7);
|
$$.Scale = int8($7);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
@ -584,7 +602,7 @@ nmem:
|
|||||||
| nam '(' LLREG '*' con ')'
|
| nam '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.Index = uint8($3);
|
$$.Index = int16($3);
|
||||||
$$.Scale = int8($5);
|
$$.Scale = int8($5);
|
||||||
checkscale($$.Scale);
|
checkscale($$.Scale);
|
||||||
}
|
}
|
||||||
@ -593,14 +611,16 @@ nam:
|
|||||||
LNAME offset '(' pointer ')'
|
LNAME offset '(' pointer ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($4);
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Name = int8($4);
|
||||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||||
$$.Offset = $2;
|
$$.Offset = $2;
|
||||||
}
|
}
|
||||||
| LNAME '<' '>' offset '(' LSB ')'
|
| LNAME '<' '>' offset '(' LSB ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_STATIC;
|
$$.Type = obj.TYPE_MEM
|
||||||
|
$$.Name = obj.NAME_STATIC
|
||||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
||||||
$$.Offset = $4;
|
$$.Offset = $4;
|
||||||
}
|
}
|
||||||
@ -622,7 +642,7 @@ pointer:
|
|||||||
LSB
|
LSB
|
||||||
| LSP
|
| LSP
|
||||||
{
|
{
|
||||||
$$ = D_AUTO;
|
$$ = obj.NAME_AUTO;
|
||||||
}
|
}
|
||||||
| LFP
|
| LFP
|
||||||
|
|
||||||
|
@ -86,78 +86,78 @@ func yyparse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lexinit = []asm.Lextab{
|
var lexinit = []asm.Lextab{
|
||||||
{"SP", LSP, i386.D_AUTO},
|
{"SP", LSP, obj.NAME_AUTO},
|
||||||
{"SB", LSB, i386.D_EXTERN},
|
{"SB", LSB, obj.NAME_EXTERN},
|
||||||
{"FP", LFP, i386.D_PARAM},
|
{"FP", LFP, obj.NAME_PARAM},
|
||||||
{"PC", LPC, i386.D_BRANCH},
|
{"PC", LPC, obj.TYPE_BRANCH},
|
||||||
{"AL", LBREG, i386.D_AL},
|
{"AL", LBREG, i386.REG_AL},
|
||||||
{"CL", LBREG, i386.D_CL},
|
{"CL", LBREG, i386.REG_CL},
|
||||||
{"DL", LBREG, i386.D_DL},
|
{"DL", LBREG, i386.REG_DL},
|
||||||
{"BL", LBREG, i386.D_BL},
|
{"BL", LBREG, i386.REG_BL},
|
||||||
{"AH", LBREG, i386.D_AH},
|
{"AH", LBREG, i386.REG_AH},
|
||||||
{"CH", LBREG, i386.D_CH},
|
{"CH", LBREG, i386.REG_CH},
|
||||||
{"DH", LBREG, i386.D_DH},
|
{"DH", LBREG, i386.REG_DH},
|
||||||
{"BH", LBREG, i386.D_BH},
|
{"BH", LBREG, i386.REG_BH},
|
||||||
{"AX", LLREG, i386.D_AX},
|
{"AX", LLREG, i386.REG_AX},
|
||||||
{"CX", LLREG, i386.D_CX},
|
{"CX", LLREG, i386.REG_CX},
|
||||||
{"DX", LLREG, i386.D_DX},
|
{"DX", LLREG, i386.REG_DX},
|
||||||
{"BX", LLREG, i386.D_BX},
|
{"BX", LLREG, i386.REG_BX},
|
||||||
/* "SP", LLREG, D_SP, */
|
/* "SP", LLREG, REG_SP, */
|
||||||
{"BP", LLREG, i386.D_BP},
|
{"BP", LLREG, i386.REG_BP},
|
||||||
{"SI", LLREG, i386.D_SI},
|
{"SI", LLREG, i386.REG_SI},
|
||||||
{"DI", LLREG, i386.D_DI},
|
{"DI", LLREG, i386.REG_DI},
|
||||||
{"F0", LFREG, i386.D_F0 + 0},
|
{"F0", LFREG, i386.REG_F0 + 0},
|
||||||
{"F1", LFREG, i386.D_F0 + 1},
|
{"F1", LFREG, i386.REG_F0 + 1},
|
||||||
{"F2", LFREG, i386.D_F0 + 2},
|
{"F2", LFREG, i386.REG_F0 + 2},
|
||||||
{"F3", LFREG, i386.D_F0 + 3},
|
{"F3", LFREG, i386.REG_F0 + 3},
|
||||||
{"F4", LFREG, i386.D_F0 + 4},
|
{"F4", LFREG, i386.REG_F0 + 4},
|
||||||
{"F5", LFREG, i386.D_F0 + 5},
|
{"F5", LFREG, i386.REG_F0 + 5},
|
||||||
{"F6", LFREG, i386.D_F0 + 6},
|
{"F6", LFREG, i386.REG_F0 + 6},
|
||||||
{"F7", LFREG, i386.D_F0 + 7},
|
{"F7", LFREG, i386.REG_F0 + 7},
|
||||||
{"X0", LXREG, i386.D_X0 + 0},
|
{"X0", LXREG, i386.REG_X0 + 0},
|
||||||
{"X1", LXREG, i386.D_X0 + 1},
|
{"X1", LXREG, i386.REG_X0 + 1},
|
||||||
{"X2", LXREG, i386.D_X0 + 2},
|
{"X2", LXREG, i386.REG_X0 + 2},
|
||||||
{"X3", LXREG, i386.D_X0 + 3},
|
{"X3", LXREG, i386.REG_X0 + 3},
|
||||||
{"X4", LXREG, i386.D_X0 + 4},
|
{"X4", LXREG, i386.REG_X0 + 4},
|
||||||
{"X5", LXREG, i386.D_X0 + 5},
|
{"X5", LXREG, i386.REG_X0 + 5},
|
||||||
{"X6", LXREG, i386.D_X0 + 6},
|
{"X6", LXREG, i386.REG_X0 + 6},
|
||||||
{"X7", LXREG, i386.D_X0 + 7},
|
{"X7", LXREG, i386.REG_X0 + 7},
|
||||||
{"CS", LSREG, i386.D_CS},
|
{"CS", LSREG, i386.REG_CS},
|
||||||
{"SS", LSREG, i386.D_SS},
|
{"SS", LSREG, i386.REG_SS},
|
||||||
{"DS", LSREG, i386.D_DS},
|
{"DS", LSREG, i386.REG_DS},
|
||||||
{"ES", LSREG, i386.D_ES},
|
{"ES", LSREG, i386.REG_ES},
|
||||||
{"FS", LSREG, i386.D_FS},
|
{"FS", LSREG, i386.REG_FS},
|
||||||
{"GS", LSREG, i386.D_GS},
|
{"GS", LSREG, i386.REG_GS},
|
||||||
{"TLS", LSREG, i386.D_TLS},
|
{"TLS", LSREG, i386.REG_TLS},
|
||||||
{"GDTR", LBREG, i386.D_GDTR},
|
{"GDTR", LBREG, i386.REG_GDTR},
|
||||||
{"IDTR", LBREG, i386.D_IDTR},
|
{"IDTR", LBREG, i386.REG_IDTR},
|
||||||
{"LDTR", LBREG, i386.D_LDTR},
|
{"LDTR", LBREG, i386.REG_LDTR},
|
||||||
{"MSW", LBREG, i386.D_MSW},
|
{"MSW", LBREG, i386.REG_MSW},
|
||||||
{"TASK", LBREG, i386.D_TASK},
|
{"TASK", LBREG, i386.REG_TASK},
|
||||||
{"CR0", LBREG, i386.D_CR + 0},
|
{"CR0", LBREG, i386.REG_CR + 0},
|
||||||
{"CR1", LBREG, i386.D_CR + 1},
|
{"CR1", LBREG, i386.REG_CR + 1},
|
||||||
{"CR2", LBREG, i386.D_CR + 2},
|
{"CR2", LBREG, i386.REG_CR + 2},
|
||||||
{"CR3", LBREG, i386.D_CR + 3},
|
{"CR3", LBREG, i386.REG_CR + 3},
|
||||||
{"CR4", LBREG, i386.D_CR + 4},
|
{"CR4", LBREG, i386.REG_CR + 4},
|
||||||
{"CR5", LBREG, i386.D_CR + 5},
|
{"CR5", LBREG, i386.REG_CR + 5},
|
||||||
{"CR6", LBREG, i386.D_CR + 6},
|
{"CR6", LBREG, i386.REG_CR + 6},
|
||||||
{"CR7", LBREG, i386.D_CR + 7},
|
{"CR7", LBREG, i386.REG_CR + 7},
|
||||||
{"DR0", LBREG, i386.D_DR + 0},
|
{"DR0", LBREG, i386.REG_DR + 0},
|
||||||
{"DR1", LBREG, i386.D_DR + 1},
|
{"DR1", LBREG, i386.REG_DR + 1},
|
||||||
{"DR2", LBREG, i386.D_DR + 2},
|
{"DR2", LBREG, i386.REG_DR + 2},
|
||||||
{"DR3", LBREG, i386.D_DR + 3},
|
{"DR3", LBREG, i386.REG_DR + 3},
|
||||||
{"DR4", LBREG, i386.D_DR + 4},
|
{"DR4", LBREG, i386.REG_DR + 4},
|
||||||
{"DR5", LBREG, i386.D_DR + 5},
|
{"DR5", LBREG, i386.REG_DR + 5},
|
||||||
{"DR6", LBREG, i386.D_DR + 6},
|
{"DR6", LBREG, i386.REG_DR + 6},
|
||||||
{"DR7", LBREG, i386.D_DR + 7},
|
{"DR7", LBREG, i386.REG_DR + 7},
|
||||||
{"TR0", LBREG, i386.D_TR + 0},
|
{"TR0", LBREG, i386.REG_TR + 0},
|
||||||
{"TR1", LBREG, i386.D_TR + 1},
|
{"TR1", LBREG, i386.REG_TR + 1},
|
||||||
{"TR2", LBREG, i386.D_TR + 2},
|
{"TR2", LBREG, i386.REG_TR + 2},
|
||||||
{"TR3", LBREG, i386.D_TR + 3},
|
{"TR3", LBREG, i386.REG_TR + 3},
|
||||||
{"TR4", LBREG, i386.D_TR + 4},
|
{"TR4", LBREG, i386.REG_TR + 4},
|
||||||
{"TR5", LBREG, i386.D_TR + 5},
|
{"TR5", LBREG, i386.REG_TR + 5},
|
||||||
{"TR6", LBREG, i386.D_TR + 6},
|
{"TR6", LBREG, i386.REG_TR + 6},
|
||||||
{"TR7", LBREG, i386.D_TR + 7},
|
{"TR7", LBREG, i386.REG_TR + 7},
|
||||||
{"AAA", LTYPE0, i386.AAAA},
|
{"AAA", LTYPE0, i386.AAAA},
|
||||||
{"AAD", LTYPE0, i386.AAAD},
|
{"AAD", LTYPE0, i386.AAAD},
|
||||||
{"AAM", LTYPE0, i386.AAAM},
|
{"AAM", LTYPE0, i386.AAAM},
|
||||||
@ -189,7 +189,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"BTSW", LTYPE3, i386.ABTSW},
|
{"BTSW", LTYPE3, i386.ABTSW},
|
||||||
{"BTW", LTYPE3, i386.ABTW},
|
{"BTW", LTYPE3, i386.ABTW},
|
||||||
{"BYTE", LTYPE2, i386.ABYTE},
|
{"BYTE", LTYPE2, i386.ABYTE},
|
||||||
{"CALL", LTYPEC, i386.ACALL},
|
{"CALL", LTYPEC, obj.ACALL},
|
||||||
{"CLC", LTYPE0, i386.ACLC},
|
{"CLC", LTYPE0, i386.ACLC},
|
||||||
{"CLD", LTYPE0, i386.ACLD},
|
{"CLD", LTYPE0, i386.ACLD},
|
||||||
{"CLI", LTYPE0, i386.ACLI},
|
{"CLI", LTYPE0, i386.ACLI},
|
||||||
@ -208,16 +208,16 @@ var lexinit = []asm.Lextab{
|
|||||||
{"CPUID", LTYPE0, i386.ACPUID},
|
{"CPUID", LTYPE0, i386.ACPUID},
|
||||||
{"DAA", LTYPE0, i386.ADAA},
|
{"DAA", LTYPE0, i386.ADAA},
|
||||||
{"DAS", LTYPE0, i386.ADAS},
|
{"DAS", LTYPE0, i386.ADAS},
|
||||||
{"DATA", LTYPED, i386.ADATA},
|
{"DATA", LTYPED, obj.ADATA},
|
||||||
{"DECB", LTYPE1, i386.ADECB},
|
{"DECB", LTYPE1, i386.ADECB},
|
||||||
{"DECL", LTYPE1, i386.ADECL},
|
{"DECL", LTYPE1, i386.ADECL},
|
||||||
{"DECW", LTYPE1, i386.ADECW},
|
{"DECW", LTYPE1, i386.ADECW},
|
||||||
{"DIVB", LTYPE2, i386.ADIVB},
|
{"DIVB", LTYPE2, i386.ADIVB},
|
||||||
{"DIVL", LTYPE2, i386.ADIVL},
|
{"DIVL", LTYPE2, i386.ADIVL},
|
||||||
{"DIVW", LTYPE2, i386.ADIVW},
|
{"DIVW", LTYPE2, i386.ADIVW},
|
||||||
{"END", LTYPE0, i386.AEND},
|
{"END", LTYPE0, obj.AEND},
|
||||||
{"ENTER", LTYPE2, i386.AENTER},
|
{"ENTER", LTYPE2, i386.AENTER},
|
||||||
{"GLOBL", LTYPEG, i386.AGLOBL},
|
{"GLOBL", LTYPEG, obj.AGLOBL},
|
||||||
{"HLT", LTYPE0, i386.AHLT},
|
{"HLT", LTYPE0, i386.AHLT},
|
||||||
{"IDIVB", LTYPE2, i386.AIDIVB},
|
{"IDIVB", LTYPE2, i386.AIDIVB},
|
||||||
{"IDIVL", LTYPE2, i386.AIDIVL},
|
{"IDIVL", LTYPE2, i386.AIDIVL},
|
||||||
@ -285,7 +285,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"JNLE", LTYPER, i386.AJGT}, /* alternate */
|
{"JNLE", LTYPER, i386.AJGT}, /* alternate */
|
||||||
{"JCXZL", LTYPER, i386.AJCXZL},
|
{"JCXZL", LTYPER, i386.AJCXZL},
|
||||||
{"JCXZW", LTYPER, i386.AJCXZW},
|
{"JCXZW", LTYPER, i386.AJCXZW},
|
||||||
{"JMP", LTYPEC, i386.AJMP},
|
{"JMP", LTYPEC, obj.AJMP},
|
||||||
{"LAHF", LTYPE0, i386.ALAHF},
|
{"LAHF", LTYPE0, i386.ALAHF},
|
||||||
{"LARL", LTYPE3, i386.ALARL},
|
{"LARL", LTYPE3, i386.ALARL},
|
||||||
{"LARW", LTYPE3, i386.ALARW},
|
{"LARW", LTYPE3, i386.ALARW},
|
||||||
@ -322,7 +322,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"NEGB", LTYPE1, i386.ANEGB},
|
{"NEGB", LTYPE1, i386.ANEGB},
|
||||||
{"NEGL", LTYPE1, i386.ANEGL},
|
{"NEGL", LTYPE1, i386.ANEGL},
|
||||||
{"NEGW", LTYPE1, i386.ANEGW},
|
{"NEGW", LTYPE1, i386.ANEGW},
|
||||||
{"NOP", LTYPEN, i386.ANOP},
|
{"NOP", LTYPEN, obj.ANOP},
|
||||||
{"NOTB", LTYPE1, i386.ANOTB},
|
{"NOTB", LTYPE1, i386.ANOTB},
|
||||||
{"NOTL", LTYPE1, i386.ANOTL},
|
{"NOTL", LTYPE1, i386.ANOTL},
|
||||||
{"NOTW", LTYPE1, i386.ANOTW},
|
{"NOTW", LTYPE1, i386.ANOTW},
|
||||||
@ -358,7 +358,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"RDTSC", LTYPE0, i386.ARDTSC},
|
{"RDTSC", LTYPE0, i386.ARDTSC},
|
||||||
{"REP", LTYPE0, i386.AREP},
|
{"REP", LTYPE0, i386.AREP},
|
||||||
{"REPN", LTYPE0, i386.AREPN},
|
{"REPN", LTYPE0, i386.AREPN},
|
||||||
{"RET", LTYPE0, i386.ARET},
|
{"RET", LTYPE0, obj.ARET},
|
||||||
{"ROLB", LTYPE3, i386.AROLB},
|
{"ROLB", LTYPE3, i386.AROLB},
|
||||||
{"ROLL", LTYPE3, i386.AROLL},
|
{"ROLL", LTYPE3, i386.AROLL},
|
||||||
{"ROLW", LTYPE3, i386.AROLW},
|
{"ROLW", LTYPE3, i386.AROLW},
|
||||||
@ -415,7 +415,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"TESTB", LTYPE3, i386.ATESTB},
|
{"TESTB", LTYPE3, i386.ATESTB},
|
||||||
{"TESTL", LTYPE3, i386.ATESTL},
|
{"TESTL", LTYPE3, i386.ATESTL},
|
||||||
{"TESTW", LTYPE3, i386.ATESTW},
|
{"TESTW", LTYPE3, i386.ATESTW},
|
||||||
{"TEXT", LTYPET, i386.ATEXT},
|
{"TEXT", LTYPET, obj.ATEXT},
|
||||||
{"VERR", LTYPE2, i386.AVERR},
|
{"VERR", LTYPE2, i386.AVERR},
|
||||||
{"VERW", LTYPE2, i386.AVERW},
|
{"VERW", LTYPE2, i386.AVERW},
|
||||||
{"WAIT", LTYPE0, i386.AWAIT},
|
{"WAIT", LTYPE0, i386.AWAIT},
|
||||||
@ -579,7 +579,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"PREFETCHT1", LTYPE2, i386.APREFETCHT1},
|
{"PREFETCHT1", LTYPE2, i386.APREFETCHT1},
|
||||||
{"PREFETCHT2", LTYPE2, i386.APREFETCHT2},
|
{"PREFETCHT2", LTYPE2, i386.APREFETCHT2},
|
||||||
{"PREFETCHNTA", LTYPE2, i386.APREFETCHNTA},
|
{"PREFETCHNTA", LTYPE2, i386.APREFETCHNTA},
|
||||||
{"UNDEF", LTYPE0, i386.AUNDEF},
|
{"UNDEF", LTYPE0, obj.AUNDEF},
|
||||||
{"ADDPD", LTYPE3, i386.AADDPD},
|
{"ADDPD", LTYPE3, i386.AADDPD},
|
||||||
{"ADDPS", LTYPE3, i386.AADDPS},
|
{"ADDPS", LTYPE3, i386.AADDPS},
|
||||||
{"ADDSD", LTYPE3, i386.AADDSD},
|
{"ADDSD", LTYPE3, i386.AADDSD},
|
||||||
@ -696,14 +696,14 @@ var lexinit = []asm.Lextab{
|
|||||||
{"UNPCKLPS", LTYPE3, i386.AUNPCKLPS},
|
{"UNPCKLPS", LTYPE3, i386.AUNPCKLPS},
|
||||||
{"XORPD", LTYPE3, i386.AXORPD},
|
{"XORPD", LTYPE3, i386.AXORPD},
|
||||||
{"XORPS", LTYPE3, i386.AXORPS},
|
{"XORPS", LTYPE3, i386.AXORPS},
|
||||||
{"USEFIELD", LTYPEN, i386.AUSEFIELD},
|
{"USEFIELD", LTYPEN, obj.AUSEFIELD},
|
||||||
{"PCDATA", LTYPEPC, i386.APCDATA},
|
{"PCDATA", LTYPEPC, obj.APCDATA},
|
||||||
{"FUNCDATA", LTYPEF, i386.AFUNCDATA},
|
{"FUNCDATA", LTYPEF, obj.AFUNCDATA},
|
||||||
}
|
}
|
||||||
|
|
||||||
func cinit() {
|
func cinit() {
|
||||||
nullgen.Type = i386.D_NONE
|
nullgen.Type = i386.REG_NONE
|
||||||
nullgen.Index = i386.D_NONE
|
nullgen.Index = i386.REG_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkscale(scale int8) {
|
func checkscale(scale int8) {
|
||||||
@ -728,7 +728,7 @@ func cclean() {
|
|||||||
|
|
||||||
g2.from = nullgen
|
g2.from = nullgen
|
||||||
g2.to = nullgen
|
g2.to = nullgen
|
||||||
outcode(i386.AEND, &g2)
|
outcode(obj.AEND, &g2)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastpc *obj.Prog
|
var lastpc *obj.Prog
|
||||||
@ -765,7 +765,7 @@ func outcode(a int, g2 *Addr2) {
|
|||||||
lastpc = p
|
lastpc = p
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if a != i386.AGLOBL && a != i386.ADATA {
|
if a != obj.AGLOBL && a != obj.ADATA {
|
||||||
asm.PC++
|
asm.PC++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -54,7 +54,7 @@ import (
|
|||||||
%left '*' '/' '%'
|
%left '*' '/' '%'
|
||||||
%token <lval> LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
|
%token <lval> LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
|
||||||
%token <lval> LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
|
%token <lval> LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
|
||||||
%token <lval> LNOP LEND LRETT LWORD LTEXT LDATA LRETRN
|
%token <lval> LNOP LEND LRETT LWORD LTEXT LDATA LGLOBL LRETRN
|
||||||
%token <lval> LCONST LSP LSB LFP LPC LCREG LFLUSH
|
%token <lval> LCONST LSP LSB LFP LPC LCREG LFLUSH
|
||||||
%token <lval> LREG LFREG LR LCR LF LFPSCR
|
%token <lval> LREG LFREG LR LCR LF LFPSCR
|
||||||
%token <lval> LLR LCTR LSPR LSPREG LSEG LMSR
|
%token <lval> LLR LCTR LSPR LSPREG LSEG LMSR
|
||||||
@ -64,8 +64,8 @@ import (
|
|||||||
%token <sval> LSCONST
|
%token <sval> LSCONST
|
||||||
%token <sym> LNAME LLAB LVAR
|
%token <sym> LNAME LLAB LVAR
|
||||||
%type <lval> con expr pointer offset sreg
|
%type <lval> con expr pointer offset sreg
|
||||||
%type <addr> addr rreg regaddr name creg freg xlreg lr ctr
|
%type <addr> addr rreg regaddr name creg freg xlreg lr ctr textsize
|
||||||
%type <addr> imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask
|
%type <addr> imm ximm fimm rel psr lcr cbit fpscr msr mask
|
||||||
%%
|
%%
|
||||||
prog:
|
prog:
|
||||||
| prog line
|
| prog line
|
||||||
@ -107,107 +107,103 @@ inst:
|
|||||||
*/
|
*/
|
||||||
LMOVW rreg ',' rreg
|
LMOVW rreg ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW addr ',' rreg
|
| LMOVW addr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW regaddr ',' rreg
|
| LMOVW regaddr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVB rreg ',' rreg
|
| LMOVB rreg ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVB addr ',' rreg
|
| LMOVB addr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVB regaddr ',' rreg
|
| LMOVB regaddr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* load floats
|
* load floats
|
||||||
*/
|
*/
|
||||||
| LFMOV addr ',' freg
|
| LFMOV addr ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LFMOV regaddr ',' freg
|
| LFMOV regaddr ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LFMOV fimm ',' freg
|
| LFMOV fimm ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LFMOV freg ',' freg
|
| LFMOV freg ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LFMOV freg ',' addr
|
| LFMOV freg ',' addr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LFMOV freg ',' regaddr
|
| LFMOV freg ',' regaddr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* store ints and bytes
|
* store ints and bytes
|
||||||
*/
|
*/
|
||||||
| LMOVW rreg ',' addr
|
| LMOVW rreg ',' addr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW rreg ',' regaddr
|
| LMOVW rreg ',' regaddr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVB rreg ',' addr
|
| LMOVB rreg ',' addr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVB rreg ',' regaddr
|
| LMOVB rreg ',' regaddr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* store floats
|
* store floats
|
||||||
*/
|
*/
|
||||||
| LMOVW freg ',' addr
|
| LMOVW freg ',' addr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW freg ',' regaddr
|
| LMOVW freg ',' regaddr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* floating point status
|
* floating point status
|
||||||
*/
|
*/
|
||||||
| LMOVW fpscr ',' freg
|
| LMOVW fpscr ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW freg ',' fpscr
|
| LMOVW freg ',' fpscr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW freg ',' imm ',' fpscr
|
| LMOVW freg ',' imm ',' fpscr
|
||||||
{
|
{
|
||||||
outgcode(int($1), &$2, NREG, &$4, &$6);
|
outgcode(int($1), &$2, 0, &$4, &$6);
|
||||||
}
|
}
|
||||||
| LMOVW fpscr ',' creg
|
| LMOVW fpscr ',' creg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
|
||||||
| LMOVW imm ',' fpscrf
|
|
||||||
{
|
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
|
||||||
}
|
}
|
||||||
| LMTFSB imm ',' con
|
| LMTFSB imm ',' con
|
||||||
{
|
{
|
||||||
@ -218,15 +214,15 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LMOVW rreg ',' imm ',' lcr
|
| LMOVW rreg ',' imm ',' lcr
|
||||||
{
|
{
|
||||||
outgcode(int($1), &$2, NREG, &$4, &$6);
|
outgcode(int($1), &$2, 0, &$4, &$6);
|
||||||
}
|
}
|
||||||
| LMOVW rreg ',' creg
|
| LMOVW rreg ',' creg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW rreg ',' lcr
|
| LMOVW rreg ',' lcr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* integer operations
|
* integer operations
|
||||||
@ -244,15 +240,15 @@ inst:
|
|||||||
}
|
}
|
||||||
| LADDW rreg ',' imm ',' rreg
|
| LADDW rreg ',' imm ',' rreg
|
||||||
{
|
{
|
||||||
outgcode(int($1), &$2, NREG, &$4, &$6);
|
outgcode(int($1), &$2, 0, &$4, &$6);
|
||||||
}
|
}
|
||||||
| LADDW rreg ',' rreg
|
| LADDW rreg ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LADDW imm ',' rreg
|
| LADDW imm ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LLOGW rreg ',' sreg ',' rreg
|
| LLOGW rreg ',' sreg ',' rreg
|
||||||
{
|
{
|
||||||
@ -260,7 +256,7 @@ inst:
|
|||||||
}
|
}
|
||||||
| LLOGW rreg ',' rreg
|
| LLOGW rreg ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LSHW rreg ',' sreg ',' rreg
|
| LSHW rreg ',' sreg ',' rreg
|
||||||
{
|
{
|
||||||
@ -268,7 +264,7 @@ inst:
|
|||||||
}
|
}
|
||||||
| LSHW rreg ',' rreg
|
| LSHW rreg ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LSHW imm ',' sreg ',' rreg
|
| LSHW imm ',' sreg ',' rreg
|
||||||
{
|
{
|
||||||
@ -276,15 +272,15 @@ inst:
|
|||||||
}
|
}
|
||||||
| LSHW imm ',' rreg
|
| LSHW imm ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LABS rreg ',' rreg
|
| LABS rreg ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LABS rreg
|
| LABS rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$2);
|
outcode(int($1), &$2, 0, &$2);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* multiply-accumulate
|
* multiply-accumulate
|
||||||
@ -298,11 +294,11 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LMOVW imm ',' rreg
|
| LMOVW imm ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW ximm ',' rreg
|
| LMOVW ximm ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* condition register operations
|
* condition register operations
|
||||||
@ -321,35 +317,35 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LMOVW creg ',' creg
|
| LMOVW creg ',' creg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW psr ',' creg
|
| LMOVW psr ',' creg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW lcr ',' rreg
|
| LMOVW lcr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW psr ',' rreg
|
| LMOVW psr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW xlreg ',' rreg
|
| LMOVW xlreg ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW rreg ',' xlreg
|
| LMOVW rreg ',' xlreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW creg ',' psr
|
| LMOVW creg ',' psr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVW rreg ',' psr
|
| LMOVW rreg ',' psr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* branch, branch conditional
|
* branch, branch conditional
|
||||||
@ -358,39 +354,39 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LBRA rel
|
| LBRA rel
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &$2);
|
outcode(int($1), &nullgen, 0, &$2);
|
||||||
}
|
}
|
||||||
| LBRA addr
|
| LBRA addr
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &$2);
|
outcode(int($1), &nullgen, 0, &$2);
|
||||||
}
|
}
|
||||||
| LBRA '(' xlreg ')'
|
| LBRA '(' xlreg ')'
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &$3);
|
outcode(int($1), &nullgen, 0, &$3);
|
||||||
}
|
}
|
||||||
| LBRA ',' rel
|
| LBRA ',' rel
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &$3);
|
outcode(int($1), &nullgen, 0, &$3);
|
||||||
}
|
}
|
||||||
| LBRA ',' addr
|
| LBRA ',' addr
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &$3);
|
outcode(int($1), &nullgen, 0, &$3);
|
||||||
}
|
}
|
||||||
| LBRA ',' '(' xlreg ')'
|
| LBRA ',' '(' xlreg ')'
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &$4);
|
outcode(int($1), &nullgen, 0, &$4);
|
||||||
}
|
}
|
||||||
| LBRA creg ',' rel
|
| LBRA creg ',' rel
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LBRA creg ',' addr
|
| LBRA creg ',' addr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LBRA creg ',' '(' xlreg ')'
|
| LBRA creg ',' '(' xlreg ')'
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$5);
|
outcode(int($1), &$2, 0, &$5);
|
||||||
}
|
}
|
||||||
| LBRA con ',' rel
|
| LBRA con ',' rel
|
||||||
{
|
{
|
||||||
@ -408,25 +404,25 @@ inst:
|
|||||||
{
|
{
|
||||||
var g obj.Addr
|
var g obj.Addr
|
||||||
g = nullgen;
|
g = nullgen;
|
||||||
g.Type = D_CONST;
|
g.Type = obj.TYPE_CONST;
|
||||||
g.Offset = $2;
|
g.Offset = $2;
|
||||||
outcode(int($1), &g, int($4), &$6);
|
outcode(int($1), &g, int(REG_R0+$4), &$6);
|
||||||
}
|
}
|
||||||
| LBRA con ',' con ',' addr
|
| LBRA con ',' con ',' addr
|
||||||
{
|
{
|
||||||
var g obj.Addr
|
var g obj.Addr
|
||||||
g = nullgen;
|
g = nullgen;
|
||||||
g.Type = D_CONST;
|
g.Type = obj.TYPE_CONST;
|
||||||
g.Offset = $2;
|
g.Offset = $2;
|
||||||
outcode(int($1), &g, int($4), &$6);
|
outcode(int($1), &g, int(REG_R0+$4), &$6);
|
||||||
}
|
}
|
||||||
| LBRA con ',' con ',' '(' xlreg ')'
|
| LBRA con ',' con ',' '(' xlreg ')'
|
||||||
{
|
{
|
||||||
var g obj.Addr
|
var g obj.Addr
|
||||||
g = nullgen;
|
g = nullgen;
|
||||||
g.Type = D_CONST;
|
g.Type = obj.TYPE_CONST;
|
||||||
g.Offset = $2;
|
g.Offset = $2;
|
||||||
outcode(int($1), &g, int($4), &$7);
|
outcode(int($1), &g, int(REG_R0+$4), &$7);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* conditional trap
|
* conditional trap
|
||||||
@ -441,22 +437,22 @@ inst:
|
|||||||
}
|
}
|
||||||
| LTRAP rreg comma
|
| LTRAP rreg comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &nullgen);
|
outcode(int($1), &$2, 0, &nullgen);
|
||||||
}
|
}
|
||||||
| LTRAP comma
|
| LTRAP comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &nullgen);
|
outcode(int($1), &nullgen, 0, &nullgen);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* floating point operate
|
* floating point operate
|
||||||
*/
|
*/
|
||||||
| LFCONV freg ',' freg
|
| LFCONV freg ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LFADD freg ',' freg
|
| LFADD freg ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LFADD freg ',' freg ',' freg
|
| LFADD freg ',' freg ',' freg
|
||||||
{
|
{
|
||||||
@ -468,7 +464,7 @@ inst:
|
|||||||
}
|
}
|
||||||
| LFCMP freg ',' freg
|
| LFCMP freg ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LFCMP freg ',' freg ',' creg
|
| LFCMP freg ',' freg ',' creg
|
||||||
{
|
{
|
||||||
@ -479,11 +475,11 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LCMP rreg ',' rreg
|
| LCMP rreg ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LCMP rreg ',' imm
|
| LCMP rreg ',' imm
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LCMP rreg ',' rreg ',' creg
|
| LCMP rreg ',' rreg ',' creg
|
||||||
{
|
{
|
||||||
@ -517,11 +513,11 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LMOVMW addr ',' rreg
|
| LMOVMW addr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LMOVMW rreg ',' addr
|
| LMOVMW rreg ',' addr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* various indexed load/store
|
* various indexed load/store
|
||||||
@ -529,150 +525,175 @@ inst:
|
|||||||
*/
|
*/
|
||||||
| LXLD regaddr ',' rreg
|
| LXLD regaddr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LXLD regaddr ',' imm ',' rreg
|
| LXLD regaddr ',' imm ',' rreg
|
||||||
{
|
{
|
||||||
outgcode(int($1), &$2, NREG, &$4, &$6);
|
outgcode(int($1), &$2, 0, &$4, &$6);
|
||||||
}
|
}
|
||||||
| LXST rreg ',' regaddr
|
| LXST rreg ',' regaddr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LXST rreg ',' imm ',' regaddr
|
| LXST rreg ',' imm ',' regaddr
|
||||||
{
|
{
|
||||||
outgcode(int($1), &$2, NREG, &$4, &$6);
|
outgcode(int($1), &$2, 0, &$4, &$6);
|
||||||
}
|
}
|
||||||
| LXMV regaddr ',' rreg
|
| LXMV regaddr ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LXMV rreg ',' regaddr
|
| LXMV rreg ',' regaddr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LXOP regaddr
|
| LXOP regaddr
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &nullgen);
|
outcode(int($1), &$2, 0, &nullgen);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* NOP
|
* NOP
|
||||||
*/
|
*/
|
||||||
| LNOP comma
|
| LNOP comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &nullgen);
|
outcode(int($1), &nullgen, 0, &nullgen);
|
||||||
}
|
}
|
||||||
| LNOP rreg comma
|
| LNOP rreg comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &nullgen);
|
outcode(int($1), &$2, 0, &nullgen);
|
||||||
}
|
}
|
||||||
| LNOP freg comma
|
| LNOP freg comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &nullgen);
|
outcode(int($1), &$2, 0, &nullgen);
|
||||||
}
|
}
|
||||||
| LNOP ',' rreg
|
| LNOP ',' rreg
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &$3);
|
outcode(int($1), &nullgen, 0, &$3);
|
||||||
}
|
}
|
||||||
| LNOP ',' freg
|
| LNOP ',' freg
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &$3);
|
outcode(int($1), &nullgen, 0, &$3);
|
||||||
}
|
}
|
||||||
| LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
|
| LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &nullgen);
|
outcode(int($1), &$2, 0, &nullgen);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* word
|
* word
|
||||||
*/
|
*/
|
||||||
| LWORD imm comma
|
| LWORD imm comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &nullgen);
|
outcode(int($1), &$2, 0, &nullgen);
|
||||||
}
|
}
|
||||||
| LWORD ximm comma
|
| LWORD ximm comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, NREG, &nullgen);
|
outcode(int($1), &$2, 0, &nullgen);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* PCDATA
|
* PCDATA
|
||||||
*/
|
*/
|
||||||
| LPCDAT imm ',' imm
|
| LPCDAT imm ',' imm
|
||||||
{
|
{
|
||||||
if $2.Type != D_CONST || $4.Type != D_CONST {
|
if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
|
||||||
yyerror("arguments to PCDATA must be integer constants")
|
yyerror("arguments to PCDATA must be integer constants")
|
||||||
}
|
}
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* FUNCDATA
|
* FUNCDATA
|
||||||
*/
|
*/
|
||||||
| LFUNCDAT imm ',' addr
|
| LFUNCDAT imm ',' addr
|
||||||
{
|
{
|
||||||
if $2.Type != D_CONST {
|
if $2.Type != obj.TYPE_CONST {
|
||||||
yyerror("index for FUNCDATA must be integer constant")
|
yyerror("index for FUNCDATA must be integer constant")
|
||||||
}
|
}
|
||||||
if $4.Type != D_EXTERN && $4.Type != D_STATIC && $4.Type != D_OREG {
|
if $4.Type != obj.TYPE_MEM || ($4.Name != obj.NAME_EXTERN && $4.Name != obj.NAME_STATIC) {
|
||||||
yyerror("value for FUNCDATA must be symbol reference")
|
yyerror("value for FUNCDATA must be symbol reference")
|
||||||
}
|
}
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* END
|
* END
|
||||||
*/
|
*/
|
||||||
| LEND comma
|
| LEND comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &nullgen);
|
outcode(int($1), &nullgen, 0, &nullgen);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* TEXT/GLOBL
|
* TEXT
|
||||||
*/
|
*/
|
||||||
| LTEXT name ',' imm
|
| LTEXT name ',' '$' textsize
|
||||||
{
|
{
|
||||||
asm.Settext($2.Sym);
|
asm.Settext($2.Sym);
|
||||||
outcode(int($1), &$2, NREG, &$4);
|
outcode(int($1), &$2, 0, &$5);
|
||||||
}
|
}
|
||||||
| LTEXT name ',' con ',' imm
|
| LTEXT name ',' con ',' '$' textsize
|
||||||
{
|
{
|
||||||
asm.Settext($2.Sym);
|
asm.Settext($2.Sym);
|
||||||
$6.Offset &= 0xffffffff;
|
outcode(int($1), &$2, int($4), &$7);
|
||||||
$6.Offset |= -obj.ArgsSizeUnknown << 32;
|
if asm.Pass > 1 {
|
||||||
outcode(int($1), &$2, int($4), &$6);
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| LTEXT name ',' con ',' imm '-' con
|
/*
|
||||||
|
* GLOBL
|
||||||
|
*/
|
||||||
|
| LGLOBL name ',' imm
|
||||||
{
|
{
|
||||||
asm.Settext($2.Sym);
|
asm.Settext($2.Sym)
|
||||||
$6.Offset &= 0xffffffff;
|
outcode(int($1), &$2, 0, &$4)
|
||||||
$6.Offset |= ($8 & 0xffffffff) << 32;
|
|
||||||
outcode(int($1), &$2, int($4), &$6);
|
|
||||||
}
|
}
|
||||||
|
| LGLOBL name ',' con ',' imm
|
||||||
|
{
|
||||||
|
asm.Settext($2.Sym)
|
||||||
|
outcode(int($1), &$2, 0, &$6)
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DATA
|
* DATA
|
||||||
*/
|
*/
|
||||||
| LDATA name '/' con ',' imm
|
| LDATA name '/' con ',' imm
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, int($4), &$6);
|
outcode(int($1), &$2, 0, &$6);
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| LDATA name '/' con ',' ximm
|
| LDATA name '/' con ',' ximm
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, int($4), &$6);
|
outcode(int($1), &$2, 0, &$6);
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| LDATA name '/' con ',' fimm
|
| LDATA name '/' con ',' fimm
|
||||||
{
|
{
|
||||||
outcode(int($1), &$2, int($4), &$6);
|
outcode(int($1), &$2, 0, &$6);
|
||||||
|
if asm.Pass > 1 {
|
||||||
|
lastpc.From3.Type = obj.TYPE_CONST
|
||||||
|
lastpc.From3.Offset = $4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* RETURN
|
* RETURN
|
||||||
*/
|
*/
|
||||||
| LRETRN comma
|
| LRETRN comma
|
||||||
{
|
{
|
||||||
outcode(int($1), &nullgen, NREG, &nullgen);
|
outcode(int($1), &nullgen, 0, &nullgen);
|
||||||
}
|
}
|
||||||
|
|
||||||
rel:
|
rel:
|
||||||
con '(' LPC ')'
|
con '(' LPC ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_BRANCH;
|
$$.Type = obj.TYPE_BRANCH;
|
||||||
$$.Offset = $1 + int64(asm.PC);
|
$$.Offset = $1 + int64(asm.PC);
|
||||||
}
|
}
|
||||||
| LNAME offset
|
| LNAME offset
|
||||||
@ -682,7 +703,7 @@ rel:
|
|||||||
if asm.Pass == 2 && $1.Type != LLAB {
|
if asm.Pass == 2 && $1.Type != LLAB {
|
||||||
yyerror("undefined label: %s", $1.Labelname)
|
yyerror("undefined label: %s", $1.Labelname)
|
||||||
}
|
}
|
||||||
$$.Type = D_BRANCH;
|
$$.Type = obj.TYPE_BRANCH;
|
||||||
$$.Offset = $1.Value + $2;
|
$$.Offset = $1.Value + $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,8 +711,8 @@ rreg:
|
|||||||
sreg
|
sreg
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_REG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($1);
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
xlreg:
|
xlreg:
|
||||||
@ -702,45 +723,49 @@ lr:
|
|||||||
LLR
|
LLR
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SPR;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Offset = $1;
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
lcr:
|
lcr:
|
||||||
LCR
|
LCR
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_CREG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = NREG; /* whole register */
|
$$.Reg = int16($1); /* whole register */
|
||||||
}
|
}
|
||||||
|
|
||||||
ctr:
|
ctr:
|
||||||
LCTR
|
LCTR
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SPR;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Offset = $1;
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
msr:
|
msr:
|
||||||
LMSR
|
LMSR
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_MSR;
|
$$.Type = obj.TYPE_REG;
|
||||||
|
$$.Reg = int16($1)
|
||||||
}
|
}
|
||||||
|
|
||||||
psr:
|
psr:
|
||||||
LSPREG
|
LSPREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SPR;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Offset = $1;
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LSPR '(' con ')'
|
| LSPR '(' con ')'
|
||||||
{
|
{
|
||||||
|
if $3 < 0 || $3 >= 1024 {
|
||||||
|
yyerror("SPR/DCR out of range")
|
||||||
|
}
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = int16($1);
|
$$.Type = obj.TYPE_REG
|
||||||
$$.Offset = $3;
|
$$.Reg = int16($1 + $3);
|
||||||
}
|
}
|
||||||
| msr
|
| msr
|
||||||
|
|
||||||
@ -748,52 +773,44 @@ fpscr:
|
|||||||
LFPSCR
|
LFPSCR
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FPSCR;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = NREG;
|
$$.Reg = int16($1);
|
||||||
}
|
|
||||||
|
|
||||||
fpscrf:
|
|
||||||
LFPSCR '(' con ')'
|
|
||||||
{
|
|
||||||
$$ = nullgen;
|
|
||||||
$$.Type = D_FPSCR;
|
|
||||||
$$.Reg = int8($3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
freg:
|
freg:
|
||||||
LFREG
|
LFREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FREG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($1);
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LF '(' con ')'
|
| LF '(' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FREG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($3);
|
$$.Reg = int16(REG_F0 + $3);
|
||||||
}
|
}
|
||||||
|
|
||||||
creg:
|
creg:
|
||||||
LCREG
|
LCREG
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_CREG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($1);
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
| LCR '(' con ')'
|
| LCR '(' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_CREG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($3);
|
$$.Reg = int16(REG_C0 + $3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cbit: con
|
cbit: con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_REG;
|
$$.Type = obj.TYPE_REG;
|
||||||
$$.Reg = int8($1);
|
$$.Reg = int16($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
mask:
|
mask:
|
||||||
@ -803,7 +820,7 @@ mask:
|
|||||||
var v uint32
|
var v uint32
|
||||||
|
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_CONST;
|
$$.Type = obj.TYPE_CONST;
|
||||||
mb = int($1);
|
mb = int($1);
|
||||||
me = int($3);
|
me = int($3);
|
||||||
if(mb < 0 || mb > 31 || me < 0 || me > 31){
|
if(mb < 0 || mb > 31 || me < 0 || me > 31){
|
||||||
@ -819,16 +836,46 @@ mask:
|
|||||||
$$.Offset = int64(v);
|
$$.Offset = int64(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textsize:
|
||||||
|
LCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = int64($1)
|
||||||
|
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||||
|
}
|
||||||
|
| '-' LCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = -int64($2)
|
||||||
|
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||||
|
}
|
||||||
|
| LCONST '-' LCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = int64($1)
|
||||||
|
$$.U.Argsize = int32($3);
|
||||||
|
}
|
||||||
|
| '-' LCONST '-' LCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.Type = obj.TYPE_TEXTSIZE;
|
||||||
|
$$.Offset = -int64($2)
|
||||||
|
$$.U.Argsize = int32($4);
|
||||||
|
}
|
||||||
|
|
||||||
ximm:
|
ximm:
|
||||||
'$' addr
|
'$' addr
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
$$.Type = D_CONST;
|
$$.Type = obj.TYPE_ADDR;
|
||||||
}
|
}
|
||||||
| '$' LSCONST
|
| '$' LSCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_SCONST;
|
$$.Type = obj.TYPE_SCONST;
|
||||||
$$.U.Sval = $2
|
$$.U.Sval = $2
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,20 +883,20 @@ fimm:
|
|||||||
'$' LFCONST
|
'$' LFCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = $2;
|
$$.U.Dval = $2;
|
||||||
}
|
}
|
||||||
| '$' '-' LFCONST
|
| '$' '-' LFCONST
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_FCONST;
|
$$.Type = obj.TYPE_FCONST;
|
||||||
$$.U.Dval = -$3;
|
$$.U.Dval = -$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
imm: '$' con
|
imm: '$' con
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_CONST;
|
$$.Type = obj.TYPE_CONST;
|
||||||
$$.Offset = $2;
|
$$.Offset = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,22 +907,22 @@ sreg:
|
|||||||
if $$ < 0 || $$ >= NREG {
|
if $$ < 0 || $$ >= NREG {
|
||||||
print("register value out of range\n")
|
print("register value out of range\n")
|
||||||
}
|
}
|
||||||
$$ = $3;
|
$$ = REG_R0 + $3;
|
||||||
}
|
}
|
||||||
|
|
||||||
regaddr:
|
regaddr:
|
||||||
'(' sreg ')'
|
'(' sreg ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Reg = int8($2);
|
$$.Reg = int16($2);
|
||||||
$$.Offset = 0;
|
$$.Offset = 0;
|
||||||
}
|
}
|
||||||
| '(' sreg '+' sreg ')'
|
| '(' sreg '+' sreg ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Reg = int8($2);
|
$$.Reg = int16($2);
|
||||||
$$.Scale = int8($4);
|
$$.Scale = int8($4);
|
||||||
$$.Offset = 0;
|
$$.Offset = 0;
|
||||||
}
|
}
|
||||||
@ -885,8 +932,8 @@ addr:
|
|||||||
| con '(' sreg ')'
|
| con '(' sreg ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Reg = int8($3);
|
$$.Reg = int16($3);
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,7 +941,7 @@ name:
|
|||||||
con '(' pointer ')'
|
con '(' pointer ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Name = int8($3);
|
$$.Name = int8($3);
|
||||||
$$.Sym = nil;
|
$$.Sym = nil;
|
||||||
$$.Offset = $1;
|
$$.Offset = $1;
|
||||||
@ -902,7 +949,7 @@ name:
|
|||||||
| LNAME offset '(' pointer ')'
|
| LNAME offset '(' pointer ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Name = int8($4);
|
$$.Name = int8($4);
|
||||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||||
$$.Offset = $2;
|
$$.Offset = $2;
|
||||||
@ -910,8 +957,8 @@ name:
|
|||||||
| LNAME '<' '>' offset '(' LSB ')'
|
| LNAME '<' '>' offset '(' LSB ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.Type = D_OREG;
|
$$.Type = obj.TYPE_MEM;
|
||||||
$$.Name = D_STATIC;
|
$$.Name = obj.NAME_STATIC;
|
||||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||||
$$.Offset = $4;
|
$$.Offset = $4;
|
||||||
}
|
}
|
||||||
|
@ -88,92 +88,92 @@ func yyparse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lexinit = []asm.Lextab{
|
var lexinit = []asm.Lextab{
|
||||||
{"SP", LSP, ppc64.D_AUTO},
|
{"SP", LSP, obj.NAME_AUTO},
|
||||||
{"SB", LSB, ppc64.D_EXTERN},
|
{"SB", LSB, obj.NAME_EXTERN},
|
||||||
{"FP", LFP, ppc64.D_PARAM},
|
{"FP", LFP, obj.NAME_PARAM},
|
||||||
{"PC", LPC, ppc64.D_BRANCH},
|
{"PC", LPC, obj.TYPE_BRANCH},
|
||||||
{"LR", LLR, ppc64.D_LR},
|
{"LR", LLR, ppc64.REG_LR},
|
||||||
{"CTR", LCTR, ppc64.D_CTR},
|
{"CTR", LCTR, ppc64.REG_CTR},
|
||||||
{"XER", LSPREG, ppc64.D_XER},
|
{"XER", LSPREG, ppc64.REG_XER},
|
||||||
{"MSR", LMSR, ppc64.D_MSR},
|
{"MSR", LMSR, ppc64.REG_MSR},
|
||||||
{"FPSCR", LFPSCR, ppc64.D_FPSCR},
|
{"FPSCR", LFPSCR, ppc64.REG_FPSCR},
|
||||||
{"SPR", LSPR, ppc64.D_SPR},
|
{"SPR", LSPR, ppc64.REG_SPR0},
|
||||||
{"DCR", LSPR, ppc64.D_DCR},
|
{"DCR", LSPR, ppc64.REG_DCR0},
|
||||||
{"CR", LCR, 0},
|
{"CR", LCR, ppc64.REG_CR},
|
||||||
{"CR0", LCREG, 0},
|
{"CR0", LCREG, ppc64.REG_C0},
|
||||||
{"CR1", LCREG, 1},
|
{"CR1", LCREG, ppc64.REG_C1},
|
||||||
{"CR2", LCREG, 2},
|
{"CR2", LCREG, ppc64.REG_C2},
|
||||||
{"CR3", LCREG, 3},
|
{"CR3", LCREG, ppc64.REG_C3},
|
||||||
{"CR4", LCREG, 4},
|
{"CR4", LCREG, ppc64.REG_C4},
|
||||||
{"CR5", LCREG, 5},
|
{"CR5", LCREG, ppc64.REG_C5},
|
||||||
{"CR6", LCREG, 6},
|
{"CR6", LCREG, ppc64.REG_C6},
|
||||||
{"CR7", LCREG, 7},
|
{"CR7", LCREG, ppc64.REG_C7},
|
||||||
{"R", LR, 0},
|
{"R", LR, 0},
|
||||||
{"R0", LREG, 0},
|
{"R0", LREG, ppc64.REG_R0},
|
||||||
{"R1", LREG, 1},
|
{"R1", LREG, ppc64.REG_R1},
|
||||||
{"R2", LREG, 2},
|
{"R2", LREG, ppc64.REG_R2},
|
||||||
{"R3", LREG, 3},
|
{"R3", LREG, ppc64.REG_R3},
|
||||||
{"R4", LREG, 4},
|
{"R4", LREG, ppc64.REG_R4},
|
||||||
{"R5", LREG, 5},
|
{"R5", LREG, ppc64.REG_R5},
|
||||||
{"R6", LREG, 6},
|
{"R6", LREG, ppc64.REG_R6},
|
||||||
{"R7", LREG, 7},
|
{"R7", LREG, ppc64.REG_R7},
|
||||||
{"R8", LREG, 8},
|
{"R8", LREG, ppc64.REG_R8},
|
||||||
{"R9", LREG, 9},
|
{"R9", LREG, ppc64.REG_R9},
|
||||||
{"R10", LREG, 10},
|
{"R10", LREG, ppc64.REG_R10},
|
||||||
{"R11", LREG, 11},
|
{"R11", LREG, ppc64.REG_R11},
|
||||||
{"R12", LREG, 12},
|
{"R12", LREG, ppc64.REG_R12},
|
||||||
{"R13", LREG, 13},
|
{"R13", LREG, ppc64.REG_R13},
|
||||||
{"R14", LREG, 14},
|
{"R14", LREG, ppc64.REG_R14},
|
||||||
{"R15", LREG, 15},
|
{"R15", LREG, ppc64.REG_R15},
|
||||||
{"R16", LREG, 16},
|
{"R16", LREG, ppc64.REG_R16},
|
||||||
{"R17", LREG, 17},
|
{"R17", LREG, ppc64.REG_R17},
|
||||||
{"R18", LREG, 18},
|
{"R18", LREG, ppc64.REG_R18},
|
||||||
{"R19", LREG, 19},
|
{"R19", LREG, ppc64.REG_R19},
|
||||||
{"R20", LREG, 20},
|
{"R20", LREG, ppc64.REG_R20},
|
||||||
{"R21", LREG, 21},
|
{"R21", LREG, ppc64.REG_R21},
|
||||||
{"R22", LREG, 22},
|
{"R22", LREG, ppc64.REG_R22},
|
||||||
{"R23", LREG, 23},
|
{"R23", LREG, ppc64.REG_R23},
|
||||||
{"R24", LREG, 24},
|
{"R24", LREG, ppc64.REG_R24},
|
||||||
{"R25", LREG, 25},
|
{"R25", LREG, ppc64.REG_R25},
|
||||||
{"R26", LREG, 26},
|
{"R26", LREG, ppc64.REG_R26},
|
||||||
{"R27", LREG, 27},
|
{"R27", LREG, ppc64.REG_R27},
|
||||||
{"R28", LREG, 28},
|
{"R28", LREG, ppc64.REG_R28},
|
||||||
{"R29", LREG, 29},
|
{"R29", LREG, ppc64.REG_R29},
|
||||||
{"g", LREG, 30}, // avoid unintentionally clobbering g using R30
|
{"g", LREG, ppc64.REG_R30}, // avoid unintentionally clobbering g using R30
|
||||||
{"R31", LREG, 31},
|
{"R31", LREG, ppc64.REG_R31},
|
||||||
{"F", LF, 0},
|
{"F", LF, 0},
|
||||||
{"F0", LFREG, 0},
|
{"F0", LFREG, ppc64.REG_F0},
|
||||||
{"F1", LFREG, 1},
|
{"F1", LFREG, ppc64.REG_F1},
|
||||||
{"F2", LFREG, 2},
|
{"F2", LFREG, ppc64.REG_F2},
|
||||||
{"F3", LFREG, 3},
|
{"F3", LFREG, ppc64.REG_F3},
|
||||||
{"F4", LFREG, 4},
|
{"F4", LFREG, ppc64.REG_F4},
|
||||||
{"F5", LFREG, 5},
|
{"F5", LFREG, ppc64.REG_F5},
|
||||||
{"F6", LFREG, 6},
|
{"F6", LFREG, ppc64.REG_F6},
|
||||||
{"F7", LFREG, 7},
|
{"F7", LFREG, ppc64.REG_F7},
|
||||||
{"F8", LFREG, 8},
|
{"F8", LFREG, ppc64.REG_F8},
|
||||||
{"F9", LFREG, 9},
|
{"F9", LFREG, ppc64.REG_F9},
|
||||||
{"F10", LFREG, 10},
|
{"F10", LFREG, ppc64.REG_F10},
|
||||||
{"F11", LFREG, 11},
|
{"F11", LFREG, ppc64.REG_F11},
|
||||||
{"F12", LFREG, 12},
|
{"F12", LFREG, ppc64.REG_F12},
|
||||||
{"F13", LFREG, 13},
|
{"F13", LFREG, ppc64.REG_F13},
|
||||||
{"F14", LFREG, 14},
|
{"F14", LFREG, ppc64.REG_F14},
|
||||||
{"F15", LFREG, 15},
|
{"F15", LFREG, ppc64.REG_F15},
|
||||||
{"F16", LFREG, 16},
|
{"F16", LFREG, ppc64.REG_F16},
|
||||||
{"F17", LFREG, 17},
|
{"F17", LFREG, ppc64.REG_F17},
|
||||||
{"F18", LFREG, 18},
|
{"F18", LFREG, ppc64.REG_F18},
|
||||||
{"F19", LFREG, 19},
|
{"F19", LFREG, ppc64.REG_F19},
|
||||||
{"F20", LFREG, 20},
|
{"F20", LFREG, ppc64.REG_F20},
|
||||||
{"F21", LFREG, 21},
|
{"F21", LFREG, ppc64.REG_F21},
|
||||||
{"F22", LFREG, 22},
|
{"F22", LFREG, ppc64.REG_F22},
|
||||||
{"F23", LFREG, 23},
|
{"F23", LFREG, ppc64.REG_F23},
|
||||||
{"F24", LFREG, 24},
|
{"F24", LFREG, ppc64.REG_F24},
|
||||||
{"F25", LFREG, 25},
|
{"F25", LFREG, ppc64.REG_F25},
|
||||||
{"F26", LFREG, 26},
|
{"F26", LFREG, ppc64.REG_F26},
|
||||||
{"F27", LFREG, 27},
|
{"F27", LFREG, ppc64.REG_F27},
|
||||||
{"F28", LFREG, 28},
|
{"F28", LFREG, ppc64.REG_F28},
|
||||||
{"F29", LFREG, 29},
|
{"F29", LFREG, ppc64.REG_F29},
|
||||||
{"F30", LFREG, 30},
|
{"F30", LFREG, ppc64.REG_F30},
|
||||||
{"F31", LFREG, 31},
|
{"F31", LFREG, ppc64.REG_F31},
|
||||||
{"CREQV", LCROP, ppc64.ACREQV},
|
{"CREQV", LCROP, ppc64.ACREQV},
|
||||||
{"CRXOR", LCROP, ppc64.ACRXOR},
|
{"CRXOR", LCROP, ppc64.ACRXOR},
|
||||||
{"CRAND", LCROP, ppc64.ACRAND},
|
{"CRAND", LCROP, ppc64.ACRAND},
|
||||||
@ -321,7 +321,7 @@ var lexinit = []asm.Lextab{
|
|||||||
{"FMOVD", LFMOV, ppc64.AFMOVD},
|
{"FMOVD", LFMOV, ppc64.AFMOVD},
|
||||||
{"FMOVS", LFMOV, ppc64.AFMOVS},
|
{"FMOVS", LFMOV, ppc64.AFMOVS},
|
||||||
{"FMOVDCC", LFCONV, ppc64.AFMOVDCC}, /* fmr. */
|
{"FMOVDCC", LFCONV, ppc64.AFMOVDCC}, /* fmr. */
|
||||||
{"GLOBL", LTEXT, ppc64.AGLOBL},
|
{"GLOBL", LGLOBL, obj.AGLOBL},
|
||||||
{"MOVB", LMOVB, ppc64.AMOVB},
|
{"MOVB", LMOVB, ppc64.AMOVB},
|
||||||
{"MOVBZ", LMOVB, ppc64.AMOVBZ},
|
{"MOVBZ", LMOVB, ppc64.AMOVBZ},
|
||||||
{"MOVBU", LMOVB, ppc64.AMOVBU},
|
{"MOVBU", LMOVB, ppc64.AMOVBU},
|
||||||
@ -348,16 +348,16 @@ var lexinit = []asm.Lextab{
|
|||||||
{"NEGV", LABS, ppc64.ANEGV},
|
{"NEGV", LABS, ppc64.ANEGV},
|
||||||
{"NEGCC", LABS, ppc64.ANEGCC},
|
{"NEGCC", LABS, ppc64.ANEGCC},
|
||||||
{"NEGVCC", LABS, ppc64.ANEGVCC},
|
{"NEGVCC", LABS, ppc64.ANEGVCC},
|
||||||
{"NOP", LNOP, ppc64.ANOP}, /* ori 0,0,0 */
|
{"NOP", LNOP, obj.ANOP}, /* ori 0,0,0 */
|
||||||
{"SYSCALL", LNOP, ppc64.ASYSCALL},
|
{"SYSCALL", LNOP, ppc64.ASYSCALL},
|
||||||
{"UNDEF", LNOP, ppc64.AUNDEF},
|
{"UNDEF", LNOP, obj.AUNDEF},
|
||||||
{"RET", LRETRN, ppc64.ARETURN},
|
{"RET", LRETRN, obj.ARET},
|
||||||
{"RETURN", LRETRN, ppc64.ARETURN},
|
{"RETURN", LRETRN, obj.ARET},
|
||||||
{"RFI", LRETRN, ppc64.ARFI},
|
{"RFI", LRETRN, ppc64.ARFI},
|
||||||
{"RFCI", LRETRN, ppc64.ARFCI},
|
{"RFCI", LRETRN, ppc64.ARFCI},
|
||||||
{"DATA", LDATA, ppc64.ADATA},
|
{"DATA", LDATA, obj.ADATA},
|
||||||
{"END", LEND, ppc64.AEND},
|
{"END", LEND, obj.AEND},
|
||||||
{"TEXT", LTEXT, ppc64.ATEXT},
|
{"TEXT", LTEXT, obj.ATEXT},
|
||||||
|
|
||||||
/* 64-bit instructions */
|
/* 64-bit instructions */
|
||||||
{"CNTLZD", LABS, ppc64.ACNTLZD},
|
{"CNTLZD", LABS, ppc64.ACNTLZD},
|
||||||
@ -460,19 +460,15 @@ var lexinit = []asm.Lextab{
|
|||||||
{"DWORD", LWORD, ppc64.ADWORD},
|
{"DWORD", LWORD, ppc64.ADWORD},
|
||||||
{"SCHED", LSCHED, 0},
|
{"SCHED", LSCHED, 0},
|
||||||
{"NOSCHED", LSCHED, 0x80},
|
{"NOSCHED", LSCHED, 0x80},
|
||||||
{"PCDATA", LPCDAT, ppc64.APCDATA},
|
{"PCDATA", LPCDAT, obj.APCDATA},
|
||||||
{"FUNCDATA", LFUNCDAT, ppc64.AFUNCDATA},
|
{"FUNCDATA", LFUNCDAT, obj.AFUNCDATA},
|
||||||
}
|
}
|
||||||
|
|
||||||
func cinit() {
|
func cinit() {
|
||||||
nullgen.Type = ppc64.D_NONE
|
|
||||||
nullgen.Name = ppc64.D_NONE
|
|
||||||
nullgen.Reg = ppc64.NREG
|
|
||||||
nullgen.Scale = ppc64.NREG // replaced Gen.xreg with Prog.scale
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cclean() {
|
func cclean() {
|
||||||
outcode(ppc64.AEND, &nullgen, ppc64.NREG, &nullgen)
|
outcode(obj.AEND, &nullgen, 0, &nullgen)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastpc *obj.Prog
|
var lastpc *obj.Prog
|
||||||
@ -486,13 +482,13 @@ func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
|
|||||||
goto out
|
goto out
|
||||||
}
|
}
|
||||||
|
|
||||||
if g1.Scale != ppc64.NREG {
|
if g1.Scale != 0 {
|
||||||
if reg != ppc64.NREG || g2.Scale != ppc64.NREG {
|
if reg != 0 || g2.Scale != 0 {
|
||||||
yyerror("bad addressing modes")
|
yyerror("bad addressing modes")
|
||||||
}
|
}
|
||||||
reg = int(g1.Scale)
|
reg = int(g1.Scale)
|
||||||
} else if g2.Scale != ppc64.NREG {
|
} else if g2.Scale != 0 {
|
||||||
if reg != ppc64.NREG {
|
if reg != 0 {
|
||||||
yyerror("bad addressing modes")
|
yyerror("bad addressing modes")
|
||||||
}
|
}
|
||||||
reg = int(g2.Scale)
|
reg = int(g2.Scale)
|
||||||
@ -505,7 +501,7 @@ func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
|
|||||||
p.Mark |= ppc64.NOSCHED
|
p.Mark |= ppc64.NOSCHED
|
||||||
}
|
}
|
||||||
p.From = *g1
|
p.From = *g1
|
||||||
p.Reg = uint8(reg)
|
p.Reg = int16(reg)
|
||||||
p.To = *g2
|
p.To = *g2
|
||||||
p.Pc = int64(asm.PC)
|
p.Pc = int64(asm.PC)
|
||||||
|
|
||||||
@ -518,7 +514,7 @@ func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
|
|||||||
lastpc = p
|
lastpc = p
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if a != ppc64.AGLOBL && a != ppc64.ADATA {
|
if a != obj.AGLOBL && a != obj.ADATA {
|
||||||
asm.PC++
|
asm.PC++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,7 +534,7 @@ func outgcode(a int, g1 *obj.Addr, reg int, g2, g3 *obj.Addr) {
|
|||||||
p.Mark |= ppc64.NOSCHED
|
p.Mark |= ppc64.NOSCHED
|
||||||
}
|
}
|
||||||
p.From = *g1
|
p.From = *g1
|
||||||
p.Reg = uint8(reg)
|
p.Reg = int16(reg)
|
||||||
p.From3 = *g2
|
p.From3 = *g2
|
||||||
p.To = *g3
|
p.To = *g3
|
||||||
p.Pc = int64(asm.PC)
|
p.Pc = int64(asm.PC)
|
||||||
@ -552,7 +548,7 @@ func outgcode(a int, g1 *obj.Addr, reg int, g2, g3 *obj.Addr) {
|
|||||||
lastpc = p
|
lastpc = p
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if a != ppc64.AGLOBL && a != ppc64.ADATA {
|
if a != obj.AGLOBL && a != obj.ADATA {
|
||||||
asm.PC++
|
asm.PC++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1245
src/cmd/new9a/y.go
1245
src/cmd/new9a/y.go
File diff suppressed because it is too large
Load Diff
@ -364,7 +364,7 @@ func readprog(b *bufio.Reader, p *obj.Prog) {
|
|||||||
p.Lineno = int32(rdint(b))
|
p.Lineno = int32(rdint(b))
|
||||||
p.Link = rdprog(b)
|
p.Link = rdprog(b)
|
||||||
p.As = int16(rdint(b))
|
p.As = int16(rdint(b))
|
||||||
p.Reg = uint8(rdint(b))
|
p.Reg = int16(rdint(b))
|
||||||
p.Scond = uint8(rdint(b))
|
p.Scond = uint8(rdint(b))
|
||||||
p.Width = int8(rdint(b))
|
p.Width = int8(rdint(b))
|
||||||
readaddr(b, &p.From)
|
readaddr(b, &p.From)
|
||||||
@ -385,13 +385,13 @@ func readaddr(b *bufio.Reader, a *obj.Addr) {
|
|||||||
a.Sym = rdsym(b)
|
a.Sym = rdsym(b)
|
||||||
a.Gotype = rdsym(b)
|
a.Gotype = rdsym(b)
|
||||||
a.Type = int16(rdint(b))
|
a.Type = int16(rdint(b))
|
||||||
a.Index = uint8(rdint(b))
|
a.Index = int16(rdint(b))
|
||||||
a.Scale = int8(rdint(b))
|
a.Scale = int8(rdint(b))
|
||||||
a.Reg = int8(rdint(b))
|
a.Reg = int16(rdint(b))
|
||||||
a.Name = int8(rdint(b))
|
a.Name = int8(rdint(b))
|
||||||
a.Class = int8(rdint(b))
|
a.Class = int8(rdint(b))
|
||||||
a.Etype = uint8(rdint(b))
|
a.Etype = uint8(rdint(b))
|
||||||
a.Offset2 = int32(rdint(b))
|
a.U.Argsize = int32(rdint(b))
|
||||||
a.Width = rdint(b)
|
a.Width = rdint(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1930,11 +1930,13 @@ prefixof(Link *ctxt, Addr *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
oclass(Link *ctxt, Addr *a)
|
oclass(Link *ctxt, Prog *p, Addr *a)
|
||||||
{
|
{
|
||||||
vlong v;
|
vlong v;
|
||||||
int32 l;
|
int32 l;
|
||||||
|
|
||||||
|
USED(p);
|
||||||
|
|
||||||
// TODO(rsc): This special case is for SHRQ $3, AX:DX,
|
// TODO(rsc): This special case is for SHRQ $3, AX:DX,
|
||||||
// which encodes as SHRQ $32(DX*0), AX.
|
// which encodes as SHRQ $32(DX*0), AX.
|
||||||
// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
|
// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
|
||||||
@ -2756,9 +2758,9 @@ doasm(Link *ctxt, Prog *p)
|
|||||||
*ctxt->andptr++ = pre;
|
*ctxt->andptr++ = pre;
|
||||||
|
|
||||||
if(p->ft == 0)
|
if(p->ft == 0)
|
||||||
p->ft = oclass(ctxt, &p->from);
|
p->ft = oclass(ctxt, p, &p->from);
|
||||||
if(p->tt == 0)
|
if(p->tt == 0)
|
||||||
p->tt = oclass(ctxt, &p->to);
|
p->tt = oclass(ctxt, p, &p->to);
|
||||||
|
|
||||||
ft = p->ft * Ymax;
|
ft = p->ft * Ymax;
|
||||||
tt = p->tt * Ymax;
|
tt = p->tt * Ymax;
|
||||||
@ -3291,7 +3293,7 @@ bad:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctxt->diag("doasm: notfound ft=%d tt=%d %P %d %d", p->ft, p->tt, p, oclass(ctxt, &p->from), oclass(ctxt, &p->to));
|
ctxt->diag("doasm: notfound ft=%d tt=%d %P %d %d", p->ft, p->tt, p, oclass(ctxt, p, &p->from), oclass(ctxt, p, &p->to));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mfound:
|
mfound:
|
||||||
|
@ -1485,10 +1485,12 @@ prefixof(Link *ctxt, Addr *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
oclass(Link *ctxt, Addr *a)
|
oclass(Link *ctxt, Prog *p, Addr *a)
|
||||||
{
|
{
|
||||||
int32 v;
|
int32 v;
|
||||||
|
|
||||||
|
USED(p);
|
||||||
|
|
||||||
// TODO(rsc): This special case is for SHRQ $3, AX:DX,
|
// TODO(rsc): This special case is for SHRQ $3, AX:DX,
|
||||||
// which encodes as SHRQ $32(DX*0), AX.
|
// which encodes as SHRQ $32(DX*0), AX.
|
||||||
// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
|
// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
|
||||||
@ -2192,9 +2194,9 @@ doasm(Link *ctxt, Prog *p)
|
|||||||
*ctxt->andptr++ = pre;
|
*ctxt->andptr++ = pre;
|
||||||
|
|
||||||
if(p->ft == 0)
|
if(p->ft == 0)
|
||||||
p->ft = oclass(ctxt, &p->from);
|
p->ft = oclass(ctxt, p, &p->from);
|
||||||
if(p->tt == 0)
|
if(p->tt == 0)
|
||||||
p->tt = oclass(ctxt, &p->to);
|
p->tt = oclass(ctxt, p, &p->to);
|
||||||
|
|
||||||
ft = p->ft * Ymax;
|
ft = p->ft * Ymax;
|
||||||
tt = p->tt * Ymax;
|
tt = p->tt * Ymax;
|
||||||
|
@ -143,7 +143,7 @@ writeobj(Link *ctxt, Biobuf *b)
|
|||||||
// we will hard code the GOOBJ=1 behavior.
|
// we will hard code the GOOBJ=1 behavior.
|
||||||
env = getenv("GOOBJ");
|
env = getenv("GOOBJ");
|
||||||
if(env == nil)
|
if(env == nil)
|
||||||
env = "0";
|
env = "2";
|
||||||
if(atoi(env) == 0) {
|
if(atoi(env) == 0) {
|
||||||
writeobjdirect(ctxt, b);
|
writeobjdirect(ctxt, b);
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user