github.com/Rookout/GoSDK@v0.1.48/pkg/services/assembler/internal/asm/arch/arch.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE.assembler file.
     4  
     5  // Package arch defines architecture-specific information and support functions.
     6  package arch
     7  
     8  import (
     9  	"fmt"
    10  	"strings"
    11  
    12  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/obj"
    13  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/obj/arm"
    14  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/obj/arm64"
    15  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/obj/x86"
    16  )
    17  
    18  
    19  const (
    20  	RFP = -(iota + 1)
    21  	RSB
    22  	RSP
    23  	RPC
    24  )
    25  
    26  
    27  type Arch struct {
    28  	*obj.LinkArch
    29  	
    30  	Instructions map[string]obj.As
    31  	
    32  	Register map[string]int16
    33  	
    34  	RegisterPrefix map[string]bool
    35  	
    36  	RegisterNumber func(string, int16) (int16, bool)
    37  	
    38  	IsJump func(word string) bool
    39  }
    40  
    41  
    42  
    43  func nilRegisterNumber(name string, n int16) (int16, bool) {
    44  	return 0, false
    45  }
    46  
    47  
    48  
    49  func Set(GOARCH string, shared bool) *Arch {
    50  	switch GOARCH {
    51  	case "386":
    52  		return archX86(&x86.Link386)
    53  	case "amd64":
    54  		return archX86(&x86.Linkamd64)
    55  	case "arm":
    56  		return archArm()
    57  	case "arm64":
    58  		return archArm64()
    59  	}
    60  	return nil
    61  }
    62  
    63  func jumpX86(word string) bool {
    64  	return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
    65  }
    66  
    67  func archX86(linkArch *obj.LinkArch) *Arch {
    68  	register := make(map[string]int16)
    69  	
    70  	for i, s := range x86.Register {
    71  		register[s] = int16(i + x86.REG_AL)
    72  	}
    73  	
    74  	register["SB"] = RSB
    75  	register["FP"] = RFP
    76  	register["PC"] = RPC
    77  	if linkArch == &x86.Linkamd64 {
    78  		
    79  		register["g"] = x86.REGG
    80  	}
    81  	
    82  
    83  	instructions := make(map[string]obj.As)
    84  	for i, s := range obj.Anames {
    85  		instructions[s] = obj.As(i)
    86  	}
    87  	for i, s := range x86.Anames {
    88  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
    89  			instructions[s] = obj.As(i) + obj.ABaseAMD64
    90  		}
    91  	}
    92  	
    93  	instructions["JA"] = x86.AJHI   
    94  	instructions["JAE"] = x86.AJCC  
    95  	instructions["JB"] = x86.AJCS   
    96  	instructions["JBE"] = x86.AJLS  
    97  	instructions["JC"] = x86.AJCS   
    98  	instructions["JCC"] = x86.AJCC  
    99  	instructions["JCS"] = x86.AJCS  
   100  	instructions["JE"] = x86.AJEQ   
   101  	instructions["JEQ"] = x86.AJEQ  
   102  	instructions["JG"] = x86.AJGT   
   103  	instructions["JGE"] = x86.AJGE  
   104  	instructions["JGT"] = x86.AJGT  
   105  	instructions["JHI"] = x86.AJHI  
   106  	instructions["JHS"] = x86.AJCC  
   107  	instructions["JL"] = x86.AJLT   
   108  	instructions["JLE"] = x86.AJLE  
   109  	instructions["JLO"] = x86.AJCS  
   110  	instructions["JLS"] = x86.AJLS  
   111  	instructions["JLT"] = x86.AJLT  
   112  	instructions["JMI"] = x86.AJMI  
   113  	instructions["JNA"] = x86.AJLS  
   114  	instructions["JNAE"] = x86.AJCS 
   115  	instructions["JNB"] = x86.AJCC  
   116  	instructions["JNBE"] = x86.AJHI 
   117  	instructions["JNC"] = x86.AJCC  
   118  	instructions["JNE"] = x86.AJNE  
   119  	instructions["JNG"] = x86.AJLE  
   120  	instructions["JNGE"] = x86.AJLT 
   121  	instructions["JNL"] = x86.AJGE  
   122  	instructions["JNLE"] = x86.AJGT 
   123  	instructions["JNO"] = x86.AJOC  
   124  	instructions["JNP"] = x86.AJPC  
   125  	instructions["JNS"] = x86.AJPL  
   126  	instructions["JNZ"] = x86.AJNE  
   127  	instructions["JO"] = x86.AJOS   
   128  	instructions["JOC"] = x86.AJOC  
   129  	instructions["JOS"] = x86.AJOS  
   130  	instructions["JP"] = x86.AJPS   
   131  	instructions["JPC"] = x86.AJPC  
   132  	instructions["JPE"] = x86.AJPS  
   133  	instructions["JPL"] = x86.AJPL  
   134  	instructions["JPO"] = x86.AJPC  
   135  	instructions["JPS"] = x86.AJPS  
   136  	instructions["JS"] = x86.AJMI   
   137  	instructions["JZ"] = x86.AJEQ   
   138  	instructions["MASKMOVDQU"] = x86.AMASKMOVOU
   139  	instructions["MOVD"] = x86.AMOVQ
   140  	instructions["MOVDQ2Q"] = x86.AMOVQ
   141  	instructions["MOVNTDQ"] = x86.AMOVNTO
   142  	instructions["MOVOA"] = x86.AMOVO
   143  	instructions["PSLLDQ"] = x86.APSLLO
   144  	instructions["PSRLDQ"] = x86.APSRLO
   145  	instructions["PADDD"] = x86.APADDL
   146  	
   147  	instructions["MOVBELL"] = x86.AMOVBEL
   148  	instructions["MOVBEQQ"] = x86.AMOVBEQ
   149  	instructions["MOVBEWW"] = x86.AMOVBEW
   150  
   151  	return &Arch{
   152  		LinkArch:       linkArch,
   153  		Instructions:   instructions,
   154  		Register:       register,
   155  		RegisterPrefix: nil,
   156  		RegisterNumber: nilRegisterNumber,
   157  		IsJump:         jumpX86,
   158  	}
   159  }
   160  
   161  func archArm() *Arch {
   162  	register := make(map[string]int16)
   163  	
   164  	
   165  	for i := arm.REG_R0; i < arm.REG_SPSR; i++ {
   166  		register[obj.Rconv(i)] = int16(i)
   167  	}
   168  	
   169  	delete(register, "R10")
   170  	register["g"] = arm.REG_R10
   171  	for i := 0; i < 16; i++ {
   172  		register[fmt.Sprintf("C%d", i)] = int16(i)
   173  	}
   174  
   175  	
   176  	register["SB"] = RSB
   177  	register["FP"] = RFP
   178  	register["PC"] = RPC
   179  	register["SP"] = RSP
   180  	registerPrefix := map[string]bool{
   181  		"F": true,
   182  		"R": true,
   183  	}
   184  
   185  	
   186  	register["MB_SY"] = arm.REG_MB_SY
   187  	register["MB_ST"] = arm.REG_MB_ST
   188  	register["MB_ISH"] = arm.REG_MB_ISH
   189  	register["MB_ISHST"] = arm.REG_MB_ISHST
   190  	register["MB_NSH"] = arm.REG_MB_NSH
   191  	register["MB_NSHST"] = arm.REG_MB_NSHST
   192  	register["MB_OSH"] = arm.REG_MB_OSH
   193  	register["MB_OSHST"] = arm.REG_MB_OSHST
   194  
   195  	instructions := make(map[string]obj.As)
   196  	for i, s := range obj.Anames {
   197  		instructions[s] = obj.As(i)
   198  	}
   199  	for i, s := range arm.Anames {
   200  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   201  			instructions[s] = obj.As(i) + obj.ABaseARM
   202  		}
   203  	}
   204  	
   205  	instructions["B"] = obj.AJMP
   206  	instructions["BL"] = obj.ACALL
   207  	
   208  	
   209  	
   210  	instructions["MCR"] = aMCR
   211  
   212  	return &Arch{
   213  		LinkArch:       &arm.Linkarm,
   214  		Instructions:   instructions,
   215  		Register:       register,
   216  		RegisterPrefix: registerPrefix,
   217  		RegisterNumber: armRegisterNumber,
   218  		IsJump:         jumpArm,
   219  	}
   220  }
   221  
   222  func archArm64() *Arch {
   223  	register := make(map[string]int16)
   224  	
   225  	
   226  	register[obj.Rconv(arm64.REGSP)] = int16(arm64.REGSP)
   227  	for i := arm64.REG_R0; i <= arm64.REG_R31; i++ {
   228  		register[obj.Rconv(i)] = int16(i)
   229  	}
   230  	
   231  	register["R18_PLATFORM"] = register["R18"]
   232  	delete(register, "R18")
   233  	for i := arm64.REG_F0; i <= arm64.REG_F31; i++ {
   234  		register[obj.Rconv(i)] = int16(i)
   235  	}
   236  	for i := arm64.REG_V0; i <= arm64.REG_V31; i++ {
   237  		register[obj.Rconv(i)] = int16(i)
   238  	}
   239  
   240  	
   241  	for i := 0; i < len(arm64.SystemReg); i++ {
   242  		register[arm64.SystemReg[i].Name] = arm64.SystemReg[i].Reg
   243  	}
   244  
   245  	register["LR"] = arm64.REGLINK
   246  
   247  	
   248  	register["SB"] = RSB
   249  	register["FP"] = RFP
   250  	register["PC"] = RPC
   251  	register["SP"] = RSP
   252  	
   253  	delete(register, "R28")
   254  	register["g"] = arm64.REG_R28
   255  	registerPrefix := map[string]bool{
   256  		"F": true,
   257  		"R": true,
   258  		"V": true,
   259  	}
   260  
   261  	instructions := make(map[string]obj.As)
   262  	for i, s := range obj.Anames {
   263  		instructions[s] = obj.As(i)
   264  	}
   265  	for i, s := range arm64.Anames {
   266  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   267  			instructions[s] = obj.As(i) + obj.ABaseARM64
   268  		}
   269  	}
   270  	
   271  	instructions["B"] = arm64.AB
   272  	instructions["BL"] = arm64.ABL
   273  
   274  	return &Arch{
   275  		LinkArch:       &arm64.Linkarm64,
   276  		Instructions:   instructions,
   277  		Register:       register,
   278  		RegisterPrefix: registerPrefix,
   279  		RegisterNumber: arm64RegisterNumber,
   280  		IsJump:         jumpArm64,
   281  	}
   282  
   283  }