Home | History | Annotate | Download | only in arch
      1 // Do not edit. Bootstrap copy of /Volumes/Android/buildbot/src/android/build-tools/out/obj/go/src/cmd/asm/internal/arch/arm.go
      2 
      3 //line /Volumes/Android/buildbot/src/android/build-tools/out/obj/go/src/cmd/asm/internal/arch/arm.go:1
      4 // Copyright 2015 The Go Authors. All rights reserved.
      5 // Use of this source code is governed by a BSD-style
      6 // license that can be found in the LICENSE file.
      7 
      8 // This file encapsulates some of the odd characteristics of the ARM
      9 // instruction set, to minimize its interaction with the core of the
     10 // assembler.
     11 
     12 package arch
     13 
     14 import (
     15 	"strings"
     16 
     17 	"bootstrap/internal/obj"
     18 	"bootstrap/internal/obj/arm"
     19 )
     20 
     21 var armLS = map[string]uint8{
     22 	"U":  arm.C_UBIT,
     23 	"S":  arm.C_SBIT,
     24 	"W":  arm.C_WBIT,
     25 	"P":  arm.C_PBIT,
     26 	"PW": arm.C_WBIT | arm.C_PBIT,
     27 	"WP": arm.C_WBIT | arm.C_PBIT,
     28 }
     29 
     30 var armSCOND = map[string]uint8{
     31 	"EQ":  arm.C_SCOND_EQ,
     32 	"NE":  arm.C_SCOND_NE,
     33 	"CS":  arm.C_SCOND_HS,
     34 	"HS":  arm.C_SCOND_HS,
     35 	"CC":  arm.C_SCOND_LO,
     36 	"LO":  arm.C_SCOND_LO,
     37 	"MI":  arm.C_SCOND_MI,
     38 	"PL":  arm.C_SCOND_PL,
     39 	"VS":  arm.C_SCOND_VS,
     40 	"VC":  arm.C_SCOND_VC,
     41 	"HI":  arm.C_SCOND_HI,
     42 	"LS":  arm.C_SCOND_LS,
     43 	"GE":  arm.C_SCOND_GE,
     44 	"LT":  arm.C_SCOND_LT,
     45 	"GT":  arm.C_SCOND_GT,
     46 	"LE":  arm.C_SCOND_LE,
     47 	"AL":  arm.C_SCOND_NONE,
     48 	"U":   arm.C_UBIT,
     49 	"S":   arm.C_SBIT,
     50 	"W":   arm.C_WBIT,
     51 	"P":   arm.C_PBIT,
     52 	"PW":  arm.C_WBIT | arm.C_PBIT,
     53 	"WP":  arm.C_WBIT | arm.C_PBIT,
     54 	"F":   arm.C_FBIT,
     55 	"IBW": arm.C_WBIT | arm.C_PBIT | arm.C_UBIT,
     56 	"IAW": arm.C_WBIT | arm.C_UBIT,
     57 	"DBW": arm.C_WBIT | arm.C_PBIT,
     58 	"DAW": arm.C_WBIT,
     59 	"IB":  arm.C_PBIT | arm.C_UBIT,
     60 	"IA":  arm.C_UBIT,
     61 	"DB":  arm.C_PBIT,
     62 	"DA":  0,
     63 }
     64 
     65 var armJump = map[string]bool{
     66 	"B":    true,
     67 	"BL":   true,
     68 	"BEQ":  true,
     69 	"BNE":  true,
     70 	"BCS":  true,
     71 	"BHS":  true,
     72 	"BCC":  true,
     73 	"BLO":  true,
     74 	"BMI":  true,
     75 	"BPL":  true,
     76 	"BVS":  true,
     77 	"BVC":  true,
     78 	"BHI":  true,
     79 	"BLS":  true,
     80 	"BGE":  true,
     81 	"BLT":  true,
     82 	"BGT":  true,
     83 	"BLE":  true,
     84 	"CALL": true,
     85 	"JMP":  true,
     86 }
     87 
     88 func jumpArm(word string) bool {
     89 	return armJump[word]
     90 }
     91 
     92 // IsARMCMP reports whether the op (as defined by an arm.A* constant) is
     93 // one of the comparison instructions that require special handling.
     94 func IsARMCMP(op int) bool {
     95 	switch op {
     96 	case arm.ACMN, arm.ACMP, arm.ATEQ, arm.ATST:
     97 		return true
     98 	}
     99 	return false
    100 }
    101 
    102 // IsARMSTREX reports whether the op (as defined by an arm.A* constant) is
    103 // one of the STREX-like instructions that require special handling.
    104 func IsARMSTREX(op int) bool {
    105 	switch op {
    106 	case arm.ASTREX, arm.ASTREXD, arm.ASWPW, arm.ASWPBU:
    107 		return true
    108 	}
    109 	return false
    110 }
    111 
    112 // MCR is not defined by the obj/arm; instead we define it privately here.
    113 // It is encoded as an MRC with a bit inside the instruction word,
    114 // passed to arch.ARMMRCOffset.
    115 const aMCR = arm.ALAST + 1
    116 
    117 // IsARMMRC reports whether the op (as defined by an arm.A* constant) is
    118 // MRC or MCR
    119 func IsARMMRC(op int) bool {
    120 	switch op {
    121 	case arm.AMRC, aMCR: // Note: aMCR is defined in this package.
    122 		return true
    123 	}
    124 	return false
    125 }
    126 
    127 // IsARMFloatCmp reports whether the op is a floating comparison instruction.
    128 func IsARMFloatCmp(op int) bool {
    129 	switch op {
    130 	case arm.ACMPF, arm.ACMPD:
    131 		return true
    132 	}
    133 	return false
    134 }
    135 
    136 // ARMMRCOffset implements the peculiar encoding of the MRC and MCR instructions.
    137 // The difference between MRC and MCR is represented by a bit high in the word, not
    138 // in the usual way by the opcode itself. Asm must use AMRC for both instructions, so
    139 // we return the opcode for MRC so that asm doesn't need to import obj/arm.
    140 func ARMMRCOffset(op int, cond string, x0, x1, x2, x3, x4, x5 int64) (offset int64, op0 int16, ok bool) {
    141 	op1 := int64(0)
    142 	if op == arm.AMRC {
    143 		op1 = 1
    144 	}
    145 	bits, ok := ParseARMCondition(cond)
    146 	if !ok {
    147 		return
    148 	}
    149 	offset = (0xe << 24) | // opcode
    150 		(op1 << 20) | // MCR/MRC
    151 		((int64(bits) ^ arm.C_SCOND_XOR) << 28) | // scond
    152 		((x0 & 15) << 8) | //coprocessor number
    153 		((x1 & 7) << 21) | // coprocessor operation
    154 		((x2 & 15) << 12) | // ARM register
    155 		((x3 & 15) << 16) | // Crn
    156 		((x4 & 15) << 0) | // Crm
    157 		((x5 & 7) << 5) | // coprocessor information
    158 		(1 << 4) /* must be set */
    159 	return offset, arm.AMRC, true
    160 }
    161 
    162 // IsARMMULA reports whether the op (as defined by an arm.A* constant) is
    163 // MULA, MULAWT or MULAWB, the 4-operand instructions.
    164 func IsARMMULA(op int) bool {
    165 	switch op {
    166 	case arm.AMULA, arm.AMULAWB, arm.AMULAWT:
    167 		return true
    168 	}
    169 	return false
    170 }
    171 
    172 var bcode = []int{
    173 	arm.ABEQ,
    174 	arm.ABNE,
    175 	arm.ABCS,
    176 	arm.ABCC,
    177 	arm.ABMI,
    178 	arm.ABPL,
    179 	arm.ABVS,
    180 	arm.ABVC,
    181 	arm.ABHI,
    182 	arm.ABLS,
    183 	arm.ABGE,
    184 	arm.ABLT,
    185 	arm.ABGT,
    186 	arm.ABLE,
    187 	arm.AB,
    188 	obj.ANOP,
    189 }
    190 
    191 // ARMConditionCodes handles the special condition code situation for the ARM.
    192 // It returns a boolean to indicate success; failure means cond was unrecognized.
    193 func ARMConditionCodes(prog *obj.Prog, cond string) bool {
    194 	if cond == "" {
    195 		return true
    196 	}
    197 	bits, ok := ParseARMCondition(cond)
    198 	if !ok {
    199 		return false
    200 	}
    201 	/* hack to make B.NE etc. work: turn it into the corresponding conditional */
    202 	if prog.As == arm.AB {
    203 		prog.As = int16(bcode[(bits^arm.C_SCOND_XOR)&0xf])
    204 		bits = (bits &^ 0xf) | arm.C_SCOND_NONE
    205 	}
    206 	prog.Scond = bits
    207 	return true
    208 }
    209 
    210 // ParseARMCondition parses the conditions attached to an ARM instruction.
    211 // The input is a single string consisting of period-separated condition
    212 // codes, such as ".P.W". An initial period is ignored.
    213 func ParseARMCondition(cond string) (uint8, bool) {
    214 	return parseARMCondition(cond, armLS, armSCOND)
    215 }
    216 
    217 func parseARMCondition(cond string, ls, scond map[string]uint8) (uint8, bool) {
    218 	if strings.HasPrefix(cond, ".") {
    219 		cond = cond[1:]
    220 	}
    221 	if cond == "" {
    222 		return arm.C_SCOND_NONE, true
    223 	}
    224 	names := strings.Split(cond, ".")
    225 	bits := uint8(0)
    226 	for _, name := range names {
    227 		if b, present := ls[name]; present {
    228 			bits |= b
    229 			continue
    230 		}
    231 		if b, present := scond[name]; present {
    232 			bits = (bits &^ arm.C_SCOND) | b
    233 			continue
    234 		}
    235 		return 0, false
    236 	}
    237 	return bits, true
    238 }
    239 
    240 func armRegisterNumber(name string, n int16) (int16, bool) {
    241 	if n < 0 || 15 < n {
    242 		return 0, false
    243 	}
    244 	switch name {
    245 	case "R":
    246 		return arm.REG_R0 + n, true
    247 	case "F":
    248 		return arm.REG_F0 + n, true
    249 	}
    250 	return 0, false
    251 }
    252