From 6197f455f695eb959a932e15dc417c1b50a2255b Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Sun, 1 Jul 2018 20:38:18 +0000 Subject: vgo --- .../google/gops/internal/obj/addrtype_string.go | 27 - .../google/gops/internal/obj/arm/a.out.go | 338 -- .../google/gops/internal/obj/arm/anames.go | 108 - .../google/gops/internal/obj/arm/anames5.go | 73 - .../google/gops/internal/obj/arm/asm5.go | 2846 ------------ .../google/gops/internal/obj/arm/list5.go | 84 - .../google/gops/internal/obj/arm/obj5.go | 1055 ----- .../google/gops/internal/obj/arm64/a.out.go | 719 --- .../google/gops/internal/obj/arm64/anames.go | 370 -- .../google/gops/internal/obj/arm64/anames7.go | 70 - .../google/gops/internal/obj/arm64/asm7.go | 4374 ------------------ .../google/gops/internal/obj/arm64/list7.go | 115 - .../google/gops/internal/obj/arm64/obj7.go | 1005 ----- vendor/github.com/google/gops/internal/obj/data.go | 190 - vendor/github.com/google/gops/internal/obj/flag.go | 115 - .../google/gops/internal/obj/funcdata.go | 48 - vendor/github.com/google/gops/internal/obj/go.go | 86 - vendor/github.com/google/gops/internal/obj/ld.go | 92 - .../google/gops/internal/obj/line_test.go | 49 - vendor/github.com/google/gops/internal/obj/link.go | 974 ---- .../google/gops/internal/obj/mips/a.out.go | 375 -- .../google/gops/internal/obj/mips/anames.go | 113 - .../google/gops/internal/obj/mips/anames0.go | 44 - .../google/gops/internal/obj/mips/asm0.go | 1783 -------- .../google/gops/internal/obj/mips/list0.go | 85 - .../google/gops/internal/obj/mips/obj0.go | 1497 ------ vendor/github.com/google/gops/internal/obj/obj.go | 306 -- .../github.com/google/gops/internal/obj/objfile.go | 606 --- vendor/github.com/google/gops/internal/obj/pass.go | 217 - vendor/github.com/google/gops/internal/obj/pcln.go | 281 -- .../github.com/google/gops/internal/obj/plist.go | 208 - .../google/gops/internal/obj/ppc64/a.out.go | 941 ---- .../google/gops/internal/obj/ppc64/anames.go | 549 --- .../google/gops/internal/obj/ppc64/anames9.go | 49 - .../google/gops/internal/obj/ppc64/asm9.go | 4552 ------------------- .../google/gops/internal/obj/ppc64/list9.go | 105 - .../google/gops/internal/obj/ppc64/obj9.go | 1251 ----- .../google/gops/internal/obj/reloctype_string.go | 17 - .../google/gops/internal/obj/s390x/a.out.go | 926 ---- .../google/gops/internal/obj/s390x/anames.go | 675 --- .../google/gops/internal/obj/s390x/anamesz.go | 39 - .../google/gops/internal/obj/s390x/asmz.go | 4766 -------------------- .../google/gops/internal/obj/s390x/listz.go | 74 - .../google/gops/internal/obj/s390x/objz.go | 1029 ----- .../google/gops/internal/obj/s390x/vector.go | 1061 ----- .../google/gops/internal/obj/sizeof_test.go | 40 - .../github.com/google/gops/internal/obj/stack.go | 21 - .../google/gops/internal/obj/stringer.go | 104 - vendor/github.com/google/gops/internal/obj/sym.go | 88 - .../google/gops/internal/obj/symkind_string.go | 16 - .../google/gops/internal/obj/textflag.go | 50 - .../google/gops/internal/obj/typekind.go | 41 - vendor/github.com/google/gops/internal/obj/util.go | 499 -- .../google/gops/internal/obj/x86/a.out.go | 1009 ----- .../google/gops/internal/obj/x86/anames.go | 769 ---- .../google/gops/internal/obj/x86/asm6.go | 4536 ------------------- .../google/gops/internal/obj/x86/list6.go | 181 - .../google/gops/internal/obj/x86/obj6.go | 1481 ------ .../google/gops/internal/obj/zbootstrap.go | 15 - 59 files changed, 43137 deletions(-) delete mode 100644 vendor/github.com/google/gops/internal/obj/addrtype_string.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/anames5.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/asm5.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/list5.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm/obj5.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/anames7.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/asm7.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/list7.go delete mode 100644 vendor/github.com/google/gops/internal/obj/arm64/obj7.go delete mode 100644 vendor/github.com/google/gops/internal/obj/data.go delete mode 100644 vendor/github.com/google/gops/internal/obj/flag.go delete mode 100644 vendor/github.com/google/gops/internal/obj/funcdata.go delete mode 100644 vendor/github.com/google/gops/internal/obj/go.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ld.go delete mode 100644 vendor/github.com/google/gops/internal/obj/line_test.go delete mode 100644 vendor/github.com/google/gops/internal/obj/link.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/anames0.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/asm0.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/list0.go delete mode 100644 vendor/github.com/google/gops/internal/obj/mips/obj0.go delete mode 100644 vendor/github.com/google/gops/internal/obj/obj.go delete mode 100644 vendor/github.com/google/gops/internal/obj/objfile.go delete mode 100644 vendor/github.com/google/gops/internal/obj/pass.go delete mode 100644 vendor/github.com/google/gops/internal/obj/pcln.go delete mode 100644 vendor/github.com/google/gops/internal/obj/plist.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/anames9.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/asm9.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/list9.go delete mode 100644 vendor/github.com/google/gops/internal/obj/ppc64/obj9.go delete mode 100644 vendor/github.com/google/gops/internal/obj/reloctype_string.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/anamesz.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/asmz.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/listz.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/objz.go delete mode 100644 vendor/github.com/google/gops/internal/obj/s390x/vector.go delete mode 100644 vendor/github.com/google/gops/internal/obj/sizeof_test.go delete mode 100644 vendor/github.com/google/gops/internal/obj/stack.go delete mode 100644 vendor/github.com/google/gops/internal/obj/stringer.go delete mode 100644 vendor/github.com/google/gops/internal/obj/sym.go delete mode 100644 vendor/github.com/google/gops/internal/obj/symkind_string.go delete mode 100644 vendor/github.com/google/gops/internal/obj/textflag.go delete mode 100644 vendor/github.com/google/gops/internal/obj/typekind.go delete mode 100644 vendor/github.com/google/gops/internal/obj/util.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/a.out.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/anames.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/asm6.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/list6.go delete mode 100644 vendor/github.com/google/gops/internal/obj/x86/obj6.go delete mode 100644 vendor/github.com/google/gops/internal/obj/zbootstrap.go (limited to 'vendor/github.com/google/gops/internal/obj') diff --git a/vendor/github.com/google/gops/internal/obj/addrtype_string.go b/vendor/github.com/google/gops/internal/obj/addrtype_string.go deleted file mode 100644 index 48d498d..0000000 --- a/vendor/github.com/google/gops/internal/obj/addrtype_string.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by "stringer -type AddrType cmd/internal/obj"; DO NOT EDIT - -package obj - -import "fmt" - -const ( - _AddrType_name_0 = "TYPE_NONE" - _AddrType_name_1 = "TYPE_BRANCHTYPE_TEXTSIZETYPE_MEMTYPE_CONSTTYPE_FCONSTTYPE_SCONSTTYPE_REGTYPE_ADDRTYPE_SHIFTTYPE_REGREGTYPE_REGREG2TYPE_INDIRTYPE_REGLIST" -) - -var ( - _AddrType_index_0 = [...]uint8{0, 9} - _AddrType_index_1 = [...]uint8{0, 11, 24, 32, 42, 53, 64, 72, 81, 91, 102, 114, 124, 136} -) - -func (i AddrType) String() string { - switch { - case i == 0: - return _AddrType_name_0 - case 6 <= i && i <= 18: - i -= 6 - return _AddrType_name_1[_AddrType_index_1[i]:_AddrType_index_1[i+1]] - default: - return fmt.Sprintf("AddrType(%d)", i) - } -} diff --git a/vendor/github.com/google/gops/internal/obj/arm/a.out.go b/vendor/github.com/google/gops/internal/obj/arm/a.out.go deleted file mode 100644 index a3e0c18..0000000 --- a/vendor/github.com/google/gops/internal/obj/arm/a.out.go +++ /dev/null @@ -1,338 +0,0 @@ -// Inferno utils/5c/5.out.h -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5c/5.out.h -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm - -import "github.com/google/gops/internal/obj" - -//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p arm - -const ( - NSNAME = 8 - NSYM = 50 - NREG = 16 -) - -/* -1 disables use of REGARG */ -const ( - REGARG = -1 -) - -const ( - REG_R0 = obj.RBaseARM + iota // must be 16-aligned - 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 // must be 16-aligned - 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 // must be 2-aligned - REG_FPCR - - REG_CPSR // must be 2-aligned - REG_SPSR - - MAXREG - REGRET = REG_R0 - /* compiler allocates R1 up as temps */ - /* compiler allocates register variables R3 up */ - /* compiler allocates external registers R10 down */ - REGEXT = REG_R10 - /* these two registers are declared in runtime.h */ - REGG = REGEXT - 0 - REGM = REGEXT - 1 - - REGCTXT = REG_R7 - REGTMP = REG_R11 - REGSP = REG_R13 - REGLINK = REG_R14 - REGPC = REG_R15 - - NFREG = 16 - /* compiler allocates register variables F0 up */ - /* compiler allocates external registers F7 down */ - FREGRET = REG_F0 - FREGEXT = REG_F7 - FREGTMP = REG_F15 -) - -const ( - C_NONE = iota - C_REG - C_REGREG - C_REGREG2 - C_REGLIST - C_SHIFT - C_FREG - C_PSR - C_FCR - - C_RCON /* 0xff rotated */ - C_NCON /* ~RCON */ - C_SCON /* 0xffff */ - C_LCON - C_LCONADDR - C_ZFCON - C_SFCON - C_LFCON - - C_RACON - C_LACON - - C_SBRA - C_LBRA - - C_HAUTO /* halfword insn offset (-0xff to 0xff) */ - C_FAUTO /* float insn offset (0 to 0x3fc, word aligned) */ - C_HFAUTO /* both H and F */ - C_SAUTO /* -0xfff to 0xfff */ - C_LAUTO - - C_HOREG - C_FOREG - C_HFOREG - C_SOREG - C_ROREG - C_SROREG /* both nil and R */ - C_LOREG - - C_PC - C_SP - C_HREG - - C_ADDR /* reference to relocatable address */ - - // TLS "var" in local exec mode: will become a constant offset from - // thread local base that is ultimately chosen by the program linker. - C_TLS_LE - - // TLS "var" in initial exec mode: will become a memory address (chosen - // by the program linker) that the dynamic linker will fill with the - // offset from the thread local base. - C_TLS_IE - - C_TEXTSIZE - - C_GOK - - C_NCLASS /* must be the last */ -) - -const ( - AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota - AEOR - ASUB - ARSB - AADD - AADC - ASBC - ARSC - ATST - ATEQ - ACMP - ACMN - AORR - ABIC - - AMVN - - /* - * Do not reorder or fragment the conditional branch - * opcodes, or the predication code will break - */ - ABEQ - ABNE - ABCS - ABHS - ABCC - ABLO - ABMI - ABPL - ABVS - ABVC - ABHI - ABLS - ABGE - ABLT - ABGT - ABLE - - AMOVWD - AMOVWF - AMOVDW - AMOVFW - AMOVFD - AMOVDF - AMOVF - AMOVD - - ACMPF - ACMPD - AADDF - AADDD - ASUBF - ASUBD - AMULF - AMULD - ADIVF - ADIVD - ASQRTF - ASQRTD - AABSF - AABSD - ANEGF - ANEGD - - ASRL - ASRA - ASLL - AMULU - ADIVU - AMUL - ADIV - AMOD - AMODU - - AMOVB - AMOVBS - AMOVBU - AMOVH - AMOVHS - AMOVHU - AMOVW - AMOVM - ASWPBU - ASWPW - - ARFE - ASWI - AMULA - - AWORD - - AMULL - AMULAL - AMULLU - AMULALU - - ABX - ABXRET - ADWORD - - ALDREX - ASTREX - ALDREXD - ASTREXD - - APLD - - ACLZ - - AMULWT - AMULWB - AMULAWT - AMULAWB - - ADATABUNDLE - ADATABUNDLEEND - - AMRC // MRC/MCR - - ALAST - - // aliases - AB = obj.AJMP - ABL = obj.ACALL -) - -/* scond byte */ -const ( - C_SCOND = (1 << 4) - 1 - C_SBIT = 1 << 4 - C_PBIT = 1 << 5 - C_WBIT = 1 << 6 - C_FBIT = 1 << 7 /* psr flags-only */ - C_UBIT = 1 << 7 /* up bit, unsigned bit */ - - // These constants are the ARM condition codes encodings, - // XORed with 14 so that C_SCOND_NONE has value 0, - // so that a zeroed Prog.scond means "always execute". - C_SCOND_XOR = 14 - - C_SCOND_EQ = 0 ^ C_SCOND_XOR - C_SCOND_NE = 1 ^ C_SCOND_XOR - C_SCOND_HS = 2 ^ C_SCOND_XOR - C_SCOND_LO = 3 ^ C_SCOND_XOR - C_SCOND_MI = 4 ^ C_SCOND_XOR - C_SCOND_PL = 5 ^ C_SCOND_XOR - C_SCOND_VS = 6 ^ C_SCOND_XOR - C_SCOND_VC = 7 ^ C_SCOND_XOR - C_SCOND_HI = 8 ^ C_SCOND_XOR - C_SCOND_LS = 9 ^ C_SCOND_XOR - C_SCOND_GE = 10 ^ C_SCOND_XOR - C_SCOND_LT = 11 ^ C_SCOND_XOR - C_SCOND_GT = 12 ^ C_SCOND_XOR - C_SCOND_LE = 13 ^ C_SCOND_XOR - C_SCOND_NONE = 14 ^ C_SCOND_XOR - C_SCOND_NV = 15 ^ C_SCOND_XOR - - /* D_SHIFT type */ - SHIFT_LL = 0 << 5 - SHIFT_LR = 1 << 5 - SHIFT_AR = 2 << 5 - SHIFT_RR = 3 << 5 -) diff --git a/vendor/github.com/google/gops/internal/obj/arm/anames.go b/vendor/github.com/google/gops/internal/obj/arm/anames.go deleted file mode 100644 index 42abc94..0000000 --- a/vendor/github.com/google/gops/internal/obj/arm/anames.go +++ /dev/null @@ -1,108 +0,0 @@ -// Generated by stringer -i a.out.go -o anames.go -p arm -// Do not edit. - -package arm - -import "github.com/google/gops/internal/obj" - -var Anames = []string{ - obj.A_ARCHSPECIFIC: "AND", - "EOR", - "SUB", - "RSB", - "ADD", - "ADC", - "SBC", - "RSC", - "TST", - "TEQ", - "CMP", - "CMN", - "ORR", - "BIC", - "MVN", - "BEQ", - "BNE", - "BCS", - "BHS", - "BCC", - "BLO", - "BMI", - "BPL", - "BVS", - "BVC", - "BHI", - "BLS", - "BGE", - "BLT", - "BGT", - "BLE", - "MOVWD", - "MOVWF", - "MOVDW", - "MOVFW", - "MOVFD", - "MOVDF", - "MOVF", - "MOVD", - "CMPF", - "CMPD", - "ADDF", - "ADDD", - "SUBF", - "SUBD", - "MULF", - "MULD", - "DIVF", - "DIVD", - "SQRTF", - "SQRTD", - "ABSF", - "ABSD", - "NEGF", - "NEGD", - "SRL", - "SRA", - "SLL", - "MULU", - "DIVU", - "MUL", - "DIV", - "MOD", - "MODU", - "MOVB", - "MOVBS", - "MOVBU", - "MOVH", - "MOVHS", - "MOVHU", - "MOVW", - "MOVM", - "SWPBU", - "SWPW", - "RFE", - "SWI", - "MULA", - "WORD", - "MULL", - "MULAL", - "MULLU", - "MULALU", - "BX", - "BXRET", - "DWORD", - "LDREX", - "STREX", - "LDREXD", - "STREXD", - "PLD", - "CLZ", - "MULWT", - "MULWB", - "MULAWT", - "MULAWB", - "DATABUNDLE", - "DATABUNDLEEND", - "MRC", - "LAST", -} diff --git a/vendor/github.com/google/gops/internal/obj/arm/anames5.go b/vendor/github.com/google/gops/internal/obj/arm/anames5.go deleted file mode 100644 index 7fdd962..0000000 --- a/vendor/github.com/google/gops/internal/obj/arm/anames5.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package arm - -var cnames5 = []string{ - "NONE", - "REG", - "REGREG", - "REGREG2", - "REGLIST", - "SHIFT", - "FREG", - "PSR", - "FCR", - "RCON", - "NCON", - "SCON", - "LCON", - "LCONADDR", - "ZFCON", - "SFCON", - "LFCON", - "RACON", - "LACON", - "SBRA", - "LBRA", - "HAUTO", - "FAUTO", - "HFAUTO", - "SAUTO", - "LAUTO", - "HOREG", - "FOREG", - "HFOREG", - "SOREG", - "ROREG", - "SROREG", - "LOREG", - "PC", - "SP", - "HREG", - "ADDR", - "C_TLS_LE", - "C_TLS_IE", - "TEXTSIZE", - "GOK", - "NCLASS", - "SCOND = (1<<4)-1", - "SBIT = 1<<4", - "PBIT = 1<<5", - "WBIT = 1<<6", - "FBIT = 1<<7", - "UBIT = 1<<7", - "SCOND_XOR = 14", - "SCOND_EQ = 0 ^ C_SCOND_XOR", - "SCOND_NE = 1 ^ C_SCOND_XOR", - "SCOND_HS = 2 ^ C_SCOND_XOR", - "SCOND_LO = 3 ^ C_SCOND_XOR", - "SCOND_MI = 4 ^ C_SCOND_XOR", - "SCOND_PL = 5 ^ C_SCOND_XOR", - "SCOND_VS = 6 ^ C_SCOND_XOR", - "SCOND_VC = 7 ^ C_SCOND_XOR", - "SCOND_HI = 8 ^ C_SCOND_XOR", - "SCOND_LS = 9 ^ C_SCOND_XOR", - "SCOND_GE = 10 ^ C_SCOND_XOR", - "SCOND_LT = 11 ^ C_SCOND_XOR", - "SCOND_GT = 12 ^ C_SCOND_XOR", - "SCOND_LE = 13 ^ C_SCOND_XOR", - "SCOND_NONE = 14 ^ C_SCOND_XOR", - "SCOND_NV = 15 ^ C_SCOND_XOR", -} diff --git a/vendor/github.com/google/gops/internal/obj/arm/asm5.go b/vendor/github.com/google/gops/internal/obj/arm/asm5.go deleted file mode 100644 index aa8149d..0000000 --- a/vendor/github.com/google/gops/internal/obj/arm/asm5.go +++ /dev/null @@ -1,2846 +0,0 @@ -// Inferno utils/5l/span.c -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/span.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package arm - -import ( - "fmt" - "log" - "math" - "sort" - - "github.com/google/gops/internal/obj" -) - -type Optab struct { - as obj.As - a1 uint8 - a2 int8 - a3 uint8 - type_ uint8 - size int8 - param int16 - flag int8 - pcrelsiz uint8 -} - -type Opcross [32][2][32]uint8 - -const ( - LFROM = 1 << 0 - LTO = 1 << 1 - LPOOL = 1 << 2 - LPCREL = 1 << 3 -) - -var optab = []Optab{ - /* struct Optab: - OPCODE, from, prog->reg, to, type,size,param,flag */ - {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0}, - {AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, - {AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AMVN, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {ACMP, C_REG, C_REG, C_NONE, 1, 4, 0, 0, 0}, - {AADD, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0}, - {AADD, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0}, - {AMOVW, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0}, - {AMVN, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0}, - {ACMP, C_RCON, C_REG, C_NONE, 2, 4, 0, 0, 0}, - {AADD, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0}, - {AADD, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0}, - {AMVN, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0}, - {ACMP, C_SHIFT, C_REG, C_NONE, 3, 4, 0, 0, 0}, - {AMOVW, C_RACON, C_NONE, C_REG, 4, 4, REGSP, 0, 0}, - {AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, LPOOL, 0}, - {ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, - {ABX, C_NONE, C_NONE, C_SBRA, 74, 20, 0, 0, 0}, - {ABEQ, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, - {ABEQ, C_RCON, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // prediction hinted form, hint ignored - - {AB, C_NONE, C_NONE, C_ROREG, 6, 4, 0, LPOOL, 0}, - {ABL, C_NONE, C_NONE, C_ROREG, 7, 4, 0, 0, 0}, - {ABL, C_REG, C_NONE, C_ROREG, 7, 4, 0, 0, 0}, - {ABX, C_NONE, C_NONE, C_ROREG, 75, 12, 0, 0, 0}, - {ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0, 0, 0}, - {ASLL, C_RCON, C_REG, C_REG, 8, 4, 0, 0, 0}, - {ASLL, C_RCON, C_NONE, C_REG, 8, 4, 0, 0, 0}, - {ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0}, - {ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0}, - {ASWI, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0}, - {ASWI, C_NONE, C_NONE, C_LOREG, 10, 4, 0, 0, 0}, - {ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_LCONADDR, 11, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_TLS_LE, 103, 4, 0, 0, 0}, - {AWORD, C_NONE, C_NONE, C_TLS_IE, 104, 4, 0, 0, 0}, - {AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0, 0, 0}, - {AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0}, - {AMOVW, C_LCONADDR, C_NONE, C_REG, 12, 4, 0, LFROM | LPCREL, 4}, - {AADD, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0}, - {AADD, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0}, - {AMVN, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0}, - {ACMP, C_NCON, C_REG, C_NONE, 13, 8, 0, 0, 0}, - {AADD, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0}, - {AADD, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0}, - {AMVN, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0}, - {ACMP, C_LCON, C_REG, C_NONE, 13, 8, 0, LFROM, 0}, - {AMOVB, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AMOVBS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_REG, 58, 4, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, - {AMOVHS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0}, - {AMOVHU, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0}, - {AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0}, - {AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0}, - {ADIV, C_REG, C_REG, C_REG, 16, 4, 0, 0, 0}, - {ADIV, C_REG, C_NONE, C_REG, 16, 4, 0, 0, 0}, - {AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0, 0, 0}, - {AMULA, C_REG, C_REG, C_REGREG2, 17, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0}, - {AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0}, - {AMOVB, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0}, - {AMOVB, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0}, - {AMOVBS, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0}, - {AMOVBS, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0}, - {AMOVW, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVW, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVBU, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, - {AMOVBU, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4}, - {AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4}, - {AMOVBS, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AMOVBS, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AMOVBS, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4}, - {AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, - {AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, - {AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4}, - {AMOVW, C_TLS_LE, C_NONE, C_REG, 101, 4, 0, LFROM, 0}, - {AMOVW, C_TLS_IE, C_NONE, C_REG, 102, 8, 0, LFROM, 0}, - {AMOVW, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0}, - {AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0}, - {AMOVW, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4}, - {AMOVBU, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0}, - {AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0}, - {AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4}, - {AMOVW, C_LACON, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0}, - {AMOVW, C_PSR, C_NONE, C_REG, 35, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_PSR, 36, 4, 0, 0, 0}, - {AMOVW, C_RCON, C_NONE, C_PSR, 37, 4, 0, 0, 0}, - {AMOVM, C_REGLIST, C_NONE, C_SOREG, 38, 4, 0, 0, 0}, - {AMOVM, C_SOREG, C_NONE, C_REGLIST, 39, 4, 0, 0, 0}, - {ASWPW, C_SOREG, C_REG, C_REG, 40, 4, 0, 0, 0}, - {ARFE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0}, - {AMOVF, C_FREG, C_NONE, C_FAUTO, 50, 4, REGSP, 0, 0}, - {AMOVF, C_FREG, C_NONE, C_FOREG, 50, 4, 0, 0, 0}, - {AMOVF, C_FAUTO, C_NONE, C_FREG, 51, 4, REGSP, 0, 0}, - {AMOVF, C_FOREG, C_NONE, C_FREG, 51, 4, 0, 0, 0}, - {AMOVF, C_FREG, C_NONE, C_LAUTO, 52, 12, REGSP, LTO, 0}, - {AMOVF, C_FREG, C_NONE, C_LOREG, 52, 12, 0, LTO, 0}, - {AMOVF, C_LAUTO, C_NONE, C_FREG, 53, 12, REGSP, LFROM, 0}, - {AMOVF, C_LOREG, C_NONE, C_FREG, 53, 12, 0, LFROM, 0}, - {AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO | LPCREL, 4}, - {AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM | LPCREL, 4}, - {AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AADDF, C_FREG, C_REG, C_FREG, 54, 4, 0, 0, 0}, - {AMOVF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0, 0, 0}, - {AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0, 0, 0}, - {AMOVW, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0}, - {AMOVBU, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0}, - {AMOVB, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0}, - {AMOVBS, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, - {AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, - {AMOVBS, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, - {AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0}, - {AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0}, - {AMOVHS, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0}, - {AMOVHS, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0}, - {AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0}, - {AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0}, - {AMOVB, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVB, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVBS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVBS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVH, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVH, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVHS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVHS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVHU, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0}, - {AMOVHU, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0}, - {AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0}, - {AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0}, - {AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4}, - {AMOVHS, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0}, - {AMOVHS, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0}, - {AMOVHS, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4}, - {AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0}, - {AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0}, - {AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4}, - {AMOVB, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVB, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {AMOVBS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVBS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVBS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {AMOVH, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVH, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {AMOVHS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVHS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVHS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {AMOVHU, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0}, - {AMOVHU, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0}, - {AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4}, - {ALDREX, C_SOREG, C_NONE, C_REG, 77, 4, 0, 0, 0}, - {ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0}, - {AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0}, - {AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0}, - {ACMPF, C_FREG, C_REG, C_NONE, 82, 8, 0, 0, 0}, - {ACMPF, C_FREG, C_NONE, C_NONE, 83, 8, 0, 0, 0}, - {AMOVFW, C_FREG, C_NONE, C_FREG, 84, 4, 0, 0, 0}, - {AMOVWF, C_FREG, C_NONE, C_FREG, 85, 4, 0, 0, 0}, - {AMOVFW, C_FREG, C_NONE, C_REG, 86, 8, 0, 0, 0}, - {AMOVWF, C_REG, C_NONE, C_FREG, 87, 8, 0, 0, 0}, - {AMOVW, C_REG, C_NONE, C_FREG, 88, 4, 0, 0, 0}, - {AMOVW, C_FREG, C_NONE, C_REG, 89, 4, 0, 0, 0}, - {ATST, C_REG, C_NONE, C_NONE, 90, 4, 0, 0, 0}, - {ALDREXD, C_SOREG, C_NONE, C_REG, 91, 4, 0, 0, 0}, - {ASTREXD, C_SOREG, C_REG, C_REG, 92, 4, 0, 0, 0}, - {APLD, C_SOREG, C_NONE, C_NONE, 95, 4, 0, 0, 0}, - {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0, 0, 0}, - {ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0, 0, 0}, - {AMULWT, C_REG, C_REG, C_REG, 98, 4, 0, 0, 0}, - {AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0}, - {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0, 0}, - {obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0}, - {obj.AFUNCDATA, C_LCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0}, - {obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, - {obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL - {obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL - - {ADATABUNDLE, C_NONE, C_NONE, C_NONE, 100, 4, 0, 0, 0}, - {ADATABUNDLEEND, C_NONE, C_NONE, C_NONE, 100, 0, 0, 0, 0}, - {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0}, -} - -var pool struct { - start uint32 - size uint32 - extra uint32 -} - -var oprange [ALAST & obj.AMask][]Optab - -var xcmp [C_GOK + 1][C_GOK + 1]bool - -var deferreturn *obj.LSym - -// Note about encoding: Prog.scond holds the condition encoding, -// but XOR'ed with C_SCOND_XOR, so that C_SCOND_NONE == 0. -// The code that shifts the value << 28 has the responsibility -// for XORing with C_SCOND_XOR too. - -// asmoutnacl assembles the instruction p. It replaces asmout for NaCl. -// It returns the total number of bytes put in out, and it can change -// p->pc if extra padding is necessary. -// In rare cases, asmoutnacl might split p into two instructions. -// origPC is the PC for this Prog (no padding is taken into account). -func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint32) int { - size := int(o.size) - - // instruction specific - switch p.As { - default: - if out != nil { - asmout(ctxt, p, o, out) - } - - case ADATABUNDLE, // align to 16-byte boundary - ADATABUNDLEEND: // zero width instruction, just to align next instruction to 16-byte boundary - p.Pc = (p.Pc + 15) &^ 15 - - if out != nil { - asmout(ctxt, p, o, out) - } - - case obj.AUNDEF, - APLD: - size = 4 - if out != nil { - switch p.As { - case obj.AUNDEF: - out[0] = 0xe7fedef0 // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0) - - case APLD: - out[0] = 0xe1a01001 // (MOVW R1, R1) - } - } - - case AB, ABL: - if p.To.Type != obj.TYPE_MEM { - if out != nil { - asmout(ctxt, p, o, out) - } - } else { - if p.To.Offset != 0 || size != 4 || p.To.Reg > REG_R15 || p.To.Reg < REG_R0 { - ctxt.Diag("unsupported instruction: %v", p) - } - if p.Pc&15 == 12 { - p.Pc += 4 - } - if out != nil { - out[0] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03c0013f | (uint32(p.To.Reg)&15)<<12 | (uint32(p.To.Reg)&15)<<16 // BIC $0xc000000f, Rx - if p.As == AB { - out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff10 | (uint32(p.To.Reg)&15)<<0 // BX Rx - } else { // ABL - out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff30 | (uint32(p.To.Reg)&15)<<0 // BLX Rx - } - } - - size = 8 - } - - // align the last instruction (the actual BL) to the last instruction in a bundle - if p.As == ABL { - if deferreturn == nil { - deferreturn = obj.Linklookup(ctxt, "runtime.deferreturn", 0) - } - if p.To.Sym == deferreturn { - p.Pc = ((int64(origPC) + 15) &^ 15) + 16 - int64(size) - } else { - p.Pc += (16 - ((p.Pc + int64(size)) & 15)) & 15 - } - } - - case ALDREX, - ALDREXD, - AMOVB, - AMOVBS, - AMOVBU, - AMOVD, - AMOVF, - AMOVH, - AMOVHS, - AMOVHU, - AMOVM, - AMOVW, - ASTREX, - ASTREXD: - if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_R15 && p.From.Reg == REG_R13 { // MOVW.W x(R13), PC - if out != nil { - asmout(ctxt, p, o, out) - } - if size == 4 { - if out != nil { - // Note: 5c and 5g reg.c know that DIV/MOD smashes R12 - // so that this return instruction expansion is valid. - out[0] = out[0] &^ 0x3000 // change PC to R12 - out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03ccc13f // BIC $0xc000000f, R12 - out[2] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff1c // BX R12 - } - - size += 8 - if (p.Pc+int64(size))&15 == 4 { - p.Pc += 4 - } - break - } else { - // if the instruction used more than 4 bytes, then it must have used a very large - // offset to update R13, so we need to additionally mask R13. - if out != nil { - out[size/4-1] &^= 0x3000 // change PC to R12 - out[size/4] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03cdd103 // BIC $0xc0000000, R13 - out[size/4+1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03ccc13f // BIC $0xc000000f, R12 - out[size/4+2] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff1c // BX R12 - } - - // p->pc+size is only ok at 4 or 12 mod 16. - if (p.Pc+int64(size))%8 == 0 { - p.Pc += 4 - } - size += 12 - break - } - } - - if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_R15 { - ctxt.Diag("unsupported instruction (move to another register and use indirect jump instead): %v", p) - } - - if p.To.Type == obj.TYPE_MEM && p.To.Reg == REG_R13 && (p.Scond&C_WBIT != 0) && size > 4 { - // function prolog with very large frame size: MOVW.W R14,-100004(R13) - // split it into two instructions: - // ADD $-100004, R13 - // MOVW R14, 0(R13) - q := ctxt.NewProg() - - p.Scond &^= C_WBIT - *q = *p - a := &p.To - var a2 *obj.Addr - if p.To.Type == obj.TYPE_MEM { - a2 = &q.To - } else { - a2 = &q.From - } - nocache(q) - nocache(p) - - // insert q after p - q.Link = p.Link - - p.Link = q - q.Pcond = nil - - // make p into ADD $X, R13 - p.As = AADD - - p.From = *a - p.From.Reg = 0 - p.From.Type = obj.TYPE_CONST - p.To = obj.Addr{} - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R13 - - // make q into p but load/store from 0(R13) - q.Spadj = 0 - - *a2 = obj.Addr{} - a2.Type = obj.TYPE_MEM - a2.Reg = REG_R13 - a2.Sym = nil - a2.Offset = 0 - size = int(oplook(ctxt, p).size) - break - } - - if (p.To.Type == obj.TYPE_MEM && p.To.Reg != REG_R9) || // MOVW Rx, X(Ry), y != 9 - (p.From.Type == obj.TYPE_MEM && p.From.Reg != REG_R9) { // MOVW X(Rx), Ry, x != 9 - var a *obj.Addr - if p.To.Type == obj.TYPE_MEM { - a = &p.To - } else { - a = &p.From - } - reg := int(a.Reg) - if size == 4 { - // if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify. - if reg == 0 { - if out != nil { - asmout(ctxt, p, o, out) - } - } else { - if out != nil { - out[0] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03c00103 | (uint32(reg)&15)<<16 | (uint32(reg)&15)<<12 // BIC $0xc0000000, Rx - } - if p.Pc&15 == 12 { - p.Pc += 4 - } - size += 4 - if out != nil { - asmout(ctxt, p, o, out[1:]) - } - } - - break - } else { - // if a load/store instruction takes more than 1 word to implement, then - // we need to separate the instruction into two: - // 1. explicitly load the address into R11. - // 2. load/store from R11. - // This won't handle .W/.P, so we should reject such code. - if p.Scond&(C_PBIT|C_WBIT) != 0 { - ctxt.Diag("unsupported instruction (.P/.W): %v", p) - } - q := ctxt.NewProg() - *q = *p - var a2 *obj.Addr - if p.To.Type == obj.TYPE_MEM { - a2 = &q.To - } else { - a2 = &q.From - } - nocache(q) - nocache(p) - - // insert q after p - q.Link = p.Link - - p.Link = q - q.Pcond = nil - - // make p into MOVW $X(R), R11 - p.As = AMOVW - - p.From = *a - p.From.Type = obj.TYPE_ADDR - p.To = obj.Addr{} - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R11 - - // make q into p but load/store from 0(R11) - *a2 = obj.Addr{} - - a2.Type = obj.TYPE_MEM - a2.Reg = REG_R11 - a2.Sym = nil - a2.Offset = 0 - size = int(oplook(ctxt, p).size) - break - } - } else if out != nil { - asmout(ctxt, p, o, out) - } - } - - // destination register specific - if p.To.Type == obj.TYPE_REG { - switch p.To.Reg { - case REG_R9: - ctxt.Diag("invalid instruction, cannot write to R9: %v", p) - - case REG_R13: - if out != nil { - out[size/4] = 0xe3cdd103 // BIC $0xc0000000, R13 - } - if (p.Pc+int64(size))&15 == 0 { - p.Pc += 4 - } - size += 4 - } - } - - return size -} - -func span5(ctxt *obj.Link, cursym *obj.LSym) { - var p *obj.Prog - var op *obj.Prog - - p = cursym.Text - if p == nil || p.Link == nil { // handle external functions and ELF section symbols - return - } - - if oprange[AAND&obj.AMask] == nil { - buildop(ctxt) - } - - ctxt.Cursym = cursym - - ctxt.Autosize = int32(p.To.Offset + 4) - c := int32(0) - - op = p - p = p.Link - var i int - var m int - var o *Optab - for ; p != nil || ctxt.Blitrl != nil; op, p = p, p.Link { - if p == nil { - if checkpool(ctxt, op, 0) { - p = op - continue - } - - // can't happen: blitrl is not nil, but checkpool didn't flushpool - ctxt.Diag("internal inconsistency") - - break - } - - ctxt.Curp = p - p.Pc = int64(c) - o = oplook(ctxt, p) - if ctxt.Headtype != obj.Hnacl { - m = int(o.size) - } else { - m = asmoutnacl(ctxt, c, p, o, nil) - c = int32(p.Pc) // asmoutnacl might change pc for alignment - o = oplook(ctxt, p) // asmoutnacl might change p in rare cases - } - - if m%4 != 0 || p.Pc%4 != 0 { - ctxt.Diag("!pc invalid: %v size=%d", p, m) - } - - // must check literal pool here in case p generates many instructions - if ctxt.Blitrl != nil { - i = m - if checkpool(ctxt, op, i) { - p = op - continue - } - } - - if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP && p.As != obj.AUSEFIELD) { - ctxt.Diag("zero-width instruction\n%v", p) - continue - } - - switch o.flag & (LFROM | LTO | LPOOL) { - case LFROM: - addpool(ctxt, p, &p.From) - - case LTO: - addpool(ctxt, p, &p.To) - - case LPOOL: - if p.Scond&C_SCOND == C_SCOND_NONE { - flushpool(ctxt, p, 0, 0) - } - } - - if p.As == AMOVW && p.To.Type == obj.TYPE_REG && p.To.Reg == REGPC && p.Scond&C_SCOND == C_SCOND_NONE { - flushpool(ctxt, p, 0, 0) - } - c += int32(m) - } - - cursym.Size = int64(c) - - /* - * if any procedure is large enough to - * generate a large SBRA branch, then - * generate extra passes putting branches - * around jmps to fix. this is rare. - */ - times := 0 - - var bflag int - var opc int32 - var out [6 + 3]uint32 - for { - if ctxt.Debugvlog != 0 { - ctxt.Logf("%5.2f span1\n", obj.Cputime()) - } - bflag = 0 - c = 0 - times++ - cursym.Text.Pc = 0 // force re-layout the code. - for p = cursym.Text; p != nil; p = p.Link { - ctxt.Curp = p - o = oplook(ctxt, p) - if int64(c) > p.Pc { - p.Pc = int64(c) - } - - /* very large branches - if(o->type == 6 && p->pcond) { - otxt = p->pcond->pc - c; - if(otxt < 0) - otxt = -otxt; - if(otxt >= (1L<<17) - 10) { - q = emallocz(sizeof(Prog)); - q->link = p->link; - p->link = q; - q->as = AB; - q->to.type = TYPE_BRANCH; - q->pcond = p->pcond; - p->pcond = q; - q = emallocz(sizeof(Prog)); - q->link = p->link; - p->link = q; - q->as = AB; - q->to.type = TYPE_BRANCH; - q->pcond = q->link->link; - bflag = 1; - } - } - */ - opc = int32(p.Pc) - - if ctxt.Headtype != obj.Hnacl { - m = int(o.size) - } else { - m = asmoutnacl(ctxt, c, p, o, nil) - } - if p.Pc != int64(opc) { - bflag = 1 - } - - //print("%v pc changed %d to %d in iter. %d\n", p, opc, (int32)p->pc, times); - c = int32(p.Pc + int64(m)) - - if m%4 != 0 || p.Pc%4 != 0 { - ctxt.Diag("pc invalid: %v size=%d", p, m) - } - - if m/4 > len(out) { - ctxt.Diag("instruction size too large: %d > %d", m/4, len(out)) - } - if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP && p.As != obj.AUSEFIELD) { - if p.As == obj.ATEXT { - ctxt.Autosize = int32(p.To.Offset + 4) - continue - } - - ctxt.Diag("zero-width instruction\n%v", p) - continue - } - } - - cursym.Size = int64(c) - if bflag == 0 { - break - } - } - - if c%4 != 0 { - ctxt.Diag("sym->size=%d, invalid", c) - } - - /* - * lay out the code. all the pc-relative code references, - * even cross-function, are resolved now; - * only data references need to be relocated. - * with more work we could leave cross-function - * code references to be relocated too, and then - * perhaps we'd be able to parallelize the span loop above. - */ - - p = cursym.Text - ctxt.Autosize = int32(p.To.Offset + 4) - cursym.Grow(cursym.Size) - - bp := cursym.P - c = int32(p.Pc) // even p->link might need extra padding - var v int - for p = p.Link; p != nil; p = p.Link { - ctxt.Pc = p.Pc - ctxt.Curp = p - o = oplook(ctxt, p) - opc = int32(p.Pc) - if ctxt.Headtype != obj.Hnacl { - asmout(ctxt, p, o, out[:]) - m = int(o.size) - } else { - m = asmoutnacl(ctxt, c, p, o, out[:]) - if int64(opc) != p.Pc { - ctxt.Diag("asmoutnacl broken: pc changed (%d->%d) in last stage: %v", opc, int32(p.Pc), p) - } - } - - if m%4 != 0 || p.Pc%4 != 0 { - ctxt.Diag("final stage: pc invalid: %v size=%d", p, m) - } - - if int64(c) > p.Pc { - ctxt.Diag("PC padding invalid: want %#d, has %#d: %v", p.Pc, c, p) - } - for int64(c) != p.Pc { - // emit 0xe1a00000 (MOVW R0, R0) - bp[0] = 0x00 - bp = bp[1:] - - bp[0] = 0x00 - bp = bp[1:] - bp[0] = 0xa0 - bp = bp[1:] - bp[0] = 0xe1 - bp = bp[1:] - c += 4 - } - - for i = 0; i < m/4; i++ { - v = int(out[i]) - bp[0] = byte(v) - bp = bp[1:] - bp[0] = byte(v >> 8) - bp = bp[1:] - bp[0] = byte(v >> 16) - bp = bp[1:] - bp[0] = byte(v >> 24) - bp = bp[1:] - } - - c += int32(m) - } -} - -/* - * when the first reference to the literal pool threatens - * to go out of range of a 12-bit PC-relative offset, - * drop the pool now, and branch round it. - * this happens only in extended basic blocks that exceed 4k. - */ -func checkpool(ctxt *obj.Link, p *obj.Prog, sz int) bool { - if pool.size >= 0xff0 || immaddr(int32((p.Pc+int64(sz)+4)+4+int64(12+pool.size)-int64(pool.start+8))) == 0 { - return flushpool(ctxt, p, 1, 0) - } else if p.Link == nil { - return flushpool(ctxt, p, 2, 0) - } - return false -} - -func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool { - if ctxt.Blitrl != nil { - if skip != 0 { - if false && skip == 1 { - fmt.Printf("note: flush literal pool at %x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start) - } - q := ctxt.NewProg() - q.As = AB - q.To.Type = obj.TYPE_BRANCH - q.Pcond = p.Link - q.Link = ctxt.Blitrl - q.Lineno = p.Lineno - ctxt.Blitrl = q - } else if force == 0 && (p.Pc+int64(12+pool.size)-int64(pool.start) < 2048) { // 12 take into account the maximum nacl literal pool alignment padding size - return false - } - if ctxt.Headtype == obj.Hnacl && pool.size%16 != 0 { - // if pool is not multiple of 16 bytes, add an alignment marker - q := ctxt.NewProg() - - q.As = ADATABUNDLEEND - ctxt.Elitrl.Link = q - ctxt.Elitrl = q - } - - // The line number for constant pool entries doesn't really matter. - // We set it to the line number of the preceding instruction so that - // there are no deltas to encode in the pc-line tables. - for q := ctxt.Blitrl; q != nil; q = q.Link { - q.Lineno = p.Lineno - } - - ctxt.Elitrl.Link = p.Link - p.Link = ctxt.Blitrl - - ctxt.Blitrl = nil /* BUG: should refer back to values until out-of-range */ - ctxt.Elitrl = nil - pool.size = 0 - pool.start = 0 - pool.extra = 0 - return true - } - - return false -} - -func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { - var t obj.Prog - - c := aclass(ctxt, a) - - t.Ctxt = ctxt - t.As = AWORD - - switch c { - default: - t.To.Offset = a.Offset - t.To.Sym = a.Sym - t.To.Type = a.Type - t.To.Name = a.Name - - if ctxt.Flag_shared && t.To.Sym != nil { - t.Rel = p - } - - case C_SROREG, - C_LOREG, - C_ROREG, - C_FOREG, - C_SOREG, - C_HOREG, - C_FAUTO, - C_SAUTO, - C_LAUTO, - C_LACON: - t.To.Type = obj.TYPE_CONST - t.To.Offset = ctxt.Instoffset - } - - if t.Rel == nil { - for q := ctxt.Blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */ - if q.Rel == nil && q.To == t.To { - p.Pcond = q - return - } - } - } - - if ctxt.Headtype == obj.Hnacl && pool.size%16 == 0 { - // start a new data bundle - q := ctxt.NewProg() - q.As = ADATABUNDLE - q.Pc = int64(pool.size) - pool.size += 4 - if ctxt.Blitrl == nil { - ctxt.Blitrl = q - pool.start = uint32(p.Pc) - } else { - ctxt.Elitrl.Link = q - } - - ctxt.Elitrl = q - } - - q := ctxt.NewProg() - *q = t - q.Pc = int64(pool.size) - - if ctxt.Blitrl == nil { - ctxt.Blitrl = q - pool.start = uint32(p.Pc) - } else { - ctxt.Elitrl.Link = q - } - ctxt.Elitrl = q - pool.size += 4 - - p.Pcond = q -} - -func regoff(ctxt *obj.Link, a *obj.Addr) int32 { - ctxt.Instoffset = 0 - aclass(ctxt, a) - return int32(ctxt.Instoffset) -} - -func immrot(v uint32) int32 { - for i := 0; i < 16; i++ { - if v&^0xff == 0 { - return int32(uint32(int32(i)<<8) | v | 1<<25) - } - v = v<<2 | v>>30 - } - - return 0 -} - -func immaddr(v int32) int32 { - if v >= 0 && v <= 0xfff { - return v&0xfff | 1<<24 | 1<<23 /* pre indexing */ /* pre indexing, up */ - } - if v >= -0xfff && v < 0 { - return -v&0xfff | 1<<24 /* pre indexing */ - } - return 0 -} - -func immfloat(v int32) bool { - return v&0xC03 == 0 /* offset will fit in floating-point load/store */ -} - -func immhalf(v int32) bool { - if v >= 0 && v <= 0xff { - return v|1<<24|1<<23 != 0 /* pre indexing */ /* pre indexing, up */ - } - if v >= -0xff && v < 0 { - return -v&0xff|1<<24 != 0 /* pre indexing */ - } - return false -} - -func aclass(ctxt *obj.Link, a *obj.Addr) int { - switch a.Type { - case obj.TYPE_NONE: - return C_NONE - - case obj.TYPE_REG: - ctxt.Instoffset = 0 - if REG_R0 <= a.Reg && a.Reg <= REG_R15 { - return C_REG - } - if REG_F0 <= a.Reg && a.Reg <= REG_F15 { - return C_FREG - } - if a.Reg == REG_FPSR || a.Reg == REG_FPCR { - return C_FCR - } - if a.Reg == REG_CPSR || a.Reg == REG_SPSR { - return C_PSR - } - return C_GOK - - case obj.TYPE_REGREG: - return C_REGREG - - case obj.TYPE_REGREG2: - return C_REGREG2 - - case obj.TYPE_REGLIST: - return C_REGLIST - - case obj.TYPE_SHIFT: - return C_SHIFT - - case obj.TYPE_MEM: - switch a.Name { - case obj.NAME_EXTERN, - obj.NAME_GOTREF, - obj.NAME_STATIC: - if a.Sym == nil || a.Sym.Name == "" { - fmt.Printf("null sym external\n") - return C_GOK - } - - ctxt.Instoffset = 0 // s.b. unused but just in case - if a.Sym.Type == obj.STLSBSS { - if ctxt.Flag_shared { - return C_TLS_IE - } else { - return C_TLS_LE - } - } - - return C_ADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - if t := immaddr(int32(ctxt.Instoffset)); t != 0 { - if immhalf(int32(ctxt.Instoffset)) { - if immfloat(t) { - return C_HFAUTO - } - return C_HAUTO - } - - if immfloat(t) { - return C_FAUTO - } - return C_SAUTO - } - - return C_LAUTO - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 4 - if t := immaddr(int32(ctxt.Instoffset)); t != 0 { - if immhalf(int32(ctxt.Instoffset)) { - if immfloat(t) { - return C_HFAUTO - } - return C_HAUTO - } - - if immfloat(t) { - return C_FAUTO - } - return C_SAUTO - } - - return C_LAUTO - - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if t := immaddr(int32(ctxt.Instoffset)); t != 0 { - if immhalf(int32(ctxt.Instoffset)) { /* n.b. that it will also satisfy immrot */ - if immfloat(t) { - return C_HFOREG - } - return C_HOREG - } - - if immfloat(t) { - return C_FOREG /* n.b. that it will also satisfy immrot */ - } - if immrot(uint32(ctxt.Instoffset)) != 0 { - return C_SROREG - } - if immhalf(int32(ctxt.Instoffset)) { - return C_HOREG - } - return C_SOREG - } - - if immrot(uint32(ctxt.Instoffset)) != 0 { - return C_ROREG - } - return C_LOREG - } - - return C_GOK - - case obj.TYPE_FCONST: - if chipzero5(ctxt, a.Val.(float64)) >= 0 { - return C_ZFCON - } - if chipfloat5(ctxt, a.Val.(float64)) >= 0 { - return C_SFCON - } - return C_LFCON - - case obj.TYPE_TEXTSIZE: - return C_TEXTSIZE - - case obj.TYPE_CONST, - obj.TYPE_ADDR: - switch a.Name { - case obj.NAME_NONE: - ctxt.Instoffset = a.Offset - if a.Reg != 0 { - return aconsize(ctxt) - } - - if immrot(uint32(ctxt.Instoffset)) != 0 { - return C_RCON - } - if immrot(^uint32(ctxt.Instoffset)) != 0 { - return C_NCON - } - return C_LCON - - case obj.NAME_EXTERN, - obj.NAME_GOTREF, - obj.NAME_STATIC: - s := a.Sym - if s == nil { - break - } - ctxt.Instoffset = 0 // s.b. unused but just in case - return C_LCONADDR - - case obj.NAME_AUTO: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset - return aconsize(ctxt) - - case obj.NAME_PARAM: - ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 4 - return aconsize(ctxt) - } - - return C_GOK - - case obj.TYPE_BRANCH: - return C_SBRA - } - - return C_GOK -} - -func aconsize(ctxt *obj.Link) int { - if immrot(uint32(ctxt.Instoffset)) != 0 { - return C_RACON - } - if immrot(uint32(-ctxt.Instoffset)) != 0 { - return C_RACON - } - return C_LACON -} - -func prasm(p *obj.Prog) { - fmt.Printf("%v\n", p) -} - -func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { - a1 := int(p.Optab) - if a1 != 0 { - return &optab[a1-1] - } - a1 = int(p.From.Class) - if a1 == 0 { - a1 = aclass(ctxt, &p.From) + 1 - p.From.Class = int8(a1) - } - - a1-- - a3 := int(p.To.Class) - if a3 == 0 { - a3 = aclass(ctxt, &p.To) + 1 - p.To.Class = int8(a3) - } - - a3-- - a2 := C_NONE - if p.Reg != 0 { - a2 = C_REG - } - - if false { /*debug['O']*/ - fmt.Printf("oplook %v %v %v %v\n", p.As, DRconv(a1), DRconv(a2), DRconv(a3)) - fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type) - } - - ops := oprange[p.As&obj.AMask] - c1 := &xcmp[a1] - c3 := &xcmp[a3] - for i := range ops { - op := &ops[i] - if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] { - p.Optab = uint16(cap(optab) - cap(ops) + i + 1) - return op - } - } - - ctxt.Diag("illegal combination %v; %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.To.Type) - ctxt.Diag("from %d %d to %d %d\n", p.From.Type, p.From.Name, p.To.Type, p.To.Name) - prasm(p) - if ops == nil { - ops = optab - } - return &ops[0] -} - -func cmp(a int, b int) bool { - if a == b { - return true - } - switch a { - case C_LCON: - if b == C_RCON || b == C_NCON { - return true - } - - case C_LACON: - if b == C_RACON { - return true - } - - case C_LFCON: - if b == C_ZFCON || b == C_SFCON { - return true - } - - case C_HFAUTO: - return b == C_HAUTO || b == C_FAUTO - - case C_FAUTO, C_HAUTO: - return b == C_HFAUTO - - case C_SAUTO: - return cmp(C_HFAUTO, b) - - case C_LAUTO: - return cmp(C_SAUTO, b) - - case C_HFOREG: - return b == C_HOREG || b == C_FOREG - - case C_FOREG, C_HOREG: - return b == C_HFOREG - - case C_SROREG: - return cmp(C_SOREG, b) || cmp(C_ROREG, b) - - case C_SOREG, C_ROREG: - return b == C_SROREG || cmp(C_HFOREG, b) - - case C_LOREG: - return cmp(C_SROREG, b) - - case C_LBRA: - if b == C_SBRA { - return true - } - - case C_HREG: - return cmp(C_SP, b) || cmp(C_PC, b) - } - - return false -} - -type ocmp []Optab - -func (x ocmp) Len() int { - return len(x) -} - -func (x ocmp) Swap(i, j int) { - x[i], x[j] = x[j], x[i] -} - -func (x ocmp) Less(i, j int) bool { - p1 := &x[i] - p2 := &x[j] - n := int(p1.as) - int(p2.as) - if n != 0 { - return n < 0 - } - n = int(p1.a1) - int(p2.a1) - if n != 0 { - return n < 0 - } - n = int(p1.a2) - int(p2.a2) - if n != 0 { - return n < 0 - } - n = int(p1.a3) - int(p2.a3) - if n != 0 { - return n < 0 - } - return false -} - -func opset(a, b0 obj.As) { - oprange[a&obj.AMask] = oprange[b0] -} - -func buildop(ctxt *obj.Link) { - var n int - - for i := 0; i < C_GOK; i++ { - for n = 0; n < C_GOK; n++ { - if cmp(n, i) { - xcmp[i][n] = true - } - } - } - for n = 0; optab[n].as != obj.AXXX; n++ { - if optab[n].flag&LPCREL != 0 { - if ctxt.Flag_shared { - optab[n].size += int8(optab[n].pcrelsiz) - } else { - optab[n].flag &^= LPCREL - } - } - } - - sort.Sort(ocmp(optab[:n])) - for i := 0; i < n; i++ { - r := optab[i].as - r0 := r & obj.AMask - start := i - for optab[i].as == r { - i++ - } - oprange[r0] = optab[start:i] - i-- - - switch r { - default: - ctxt.Diag("unknown op in build: %v", r) - log.Fatalf("bad code") - - case AADD: - opset(AAND, r0) - opset(AEOR, r0) - opset(ASUB, r0) - opset(ARSB, r0) - opset(AADC, r0) - opset(ASBC, r0) - opset(ARSC, r0) - opset(AORR, r0) - opset(ABIC, r0) - - case ACMP: - opset(ATEQ, r0) - opset(ACMN, r0) - - case AMVN: - break - - case ABEQ: - opset(ABNE, r0) - opset(ABCS, r0) - opset(ABHS, r0) - opset(ABCC, r0) - opset(ABLO, r0) - opset(ABMI, r0) - opset(ABPL, r0) - opset(ABVS, r0) - opset(ABVC, r0) - opset(ABHI, r0) - opset(ABLS, r0) - opset(ABGE, r0) - opset(ABLT, r0) - opset(ABGT, r0) - opset(ABLE, r0) - - case ASLL: - opset(ASRL, r0) - opset(ASRA, r0) - - case AMUL: - opset(AMULU, r0) - - case ADIV: - opset(AMOD, r0) - opset(AMODU, r0) - opset(ADIVU, r0) - - case AMOVW, - AMOVB, - AMOVBS, - AMOVBU, - AMOVH, - AMOVHS, - AMOVHU: - break - - case ASWPW: - opset(ASWPBU, r0) - - case AB, - ABL, - ABX, - ABXRET, - obj.ADUFFZERO, - obj.ADUFFCOPY, - ASWI, - AWORD, - AMOVM, - ARFE, - obj.ATEXT, - obj.AUSEFIELD, - obj.ATYPE: - break - - case AADDF: - opset(AADDD, r0) - opset(ASUBF, r0) - opset(ASUBD, r0) - opset(AMULF, r0) - opset(AMULD, r0) - opset(ADIVF, r0) - opset(ADIVD, r0) - opset(ASQRTF, r0) - opset(ASQRTD, r0) - opset(AMOVFD, r0) - opset(AMOVDF, r0) - opset(AABSF, r0) - opset(AABSD, r0) - opset(ANEGF, r0) - opset(ANEGD, r0) - - case ACMPF: - opset(ACMPD, r0) - - case AMOVF: - opset(AMOVD, r0) - - case AMOVFW: - opset(AMOVDW, r0) - - case AMOVWF: - opset(AMOVWD, r0) - - case AMULL: - opset(AMULAL, r0) - opset(AMULLU, r0) - opset(AMULALU, r0) - - case AMULWT: - opset(AMULWB, r0) - - case AMULAWT: - opset(AMULAWB, r0) - - case AMULA, - ALDREX, - ASTREX, - ALDREXD, - ASTREXD, - ATST, - APLD, - obj.AUNDEF, - ACLZ, - obj.AFUNCDATA, - obj.APCDATA, - obj.ANOP, - ADATABUNDLE, - ADATABUNDLEEND: - break - } - } -} - -func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { - ctxt.Printp = p - o1 := uint32(0) - o2 := uint32(0) - o3 := uint32(0) - o4 := uint32(0) - o5 := uint32(0) - o6 := uint32(0) - ctxt.Armsize += int32(o.size) - if false { /*debug['P']*/ - fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_) - } - switch o.type_ { - default: - ctxt.Diag("unknown asm %d", o.type_) - prasm(p) - - case 0: /* pseudo ops */ - if false { /*debug['G']*/ - fmt.Printf("%x: %s: arm\n", uint32(p.Pc), p.From.Sym.Name) - } - - case 1: /* op R,[R],R */ - o1 = oprrr(ctxt, p.As, int(p.Scond)) - - rf := int(p.From.Reg) - rt := int(p.To.Reg) - r := int(p.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = 0 - } - if p.As == AMOVB || p.As == AMOVH || p.As == AMOVW || p.As == AMVN { - r = 0 - } else if r == 0 { - r = rt - } - o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 - - case 2: /* movbu $I,[R],R */ - aclass(ctxt, &p.From) - - o1 = oprrr(ctxt, p.As, int(p.Scond)) - o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - rt := int(p.To.Reg) - r := int(p.Reg) - if p.To.Type == obj.TYPE_NONE { - rt = 0 - } - if p.As == AMOVW || p.As == AMVN { - r = 0 - } else if r == 0 { - r = rt - } - o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 - - case 3: /* add R<<[IR],[R],R */ - o1 = mov(ctxt, p) - - case 4: /* MOVW $off(R), R -> add $off,[R],R */ - aclass(ctxt, &p.From) - if ctxt.Instoffset < 0 { - o1 = oprrr(ctxt, ASUB, int(p.Scond)) - o1 |= uint32(immrot(uint32(-ctxt.Instoffset))) - } else { - o1 = oprrr(ctxt, AADD, int(p.Scond)) - o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - } - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 |= (uint32(r) & 15) << 16 - o1 |= (uint32(p.To.Reg) & 15) << 12 - - case 5: /* bra s */ - o1 = opbra(ctxt, p, p.As, int(p.Scond)) - - v := int32(-8) - if p.To.Sym != nil { - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 4 - rel.Sym = p.To.Sym - v += int32(p.To.Offset) - rel.Add = int64(o1) | (int64(v)>>2)&0xffffff - rel.Type = obj.R_CALLARM - break - } - - if p.Pcond != nil { - v = int32((p.Pcond.Pc - ctxt.Pc) - 8) - } - o1 |= (uint32(v) >> 2) & 0xffffff - - case 6: /* b ,O(R) -> add $O,R,PC */ - aclass(ctxt, &p.To) - - o1 = oprrr(ctxt, AADD, int(p.Scond)) - o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - o1 |= (uint32(p.To.Reg) & 15) << 16 - o1 |= (REGPC & 15) << 12 - - case 7: /* bl (R) -> blx R */ - aclass(ctxt, &p.To) - - if ctxt.Instoffset != 0 { - ctxt.Diag("%v: doesn't support BL offset(REG) with non-zero offset %d", p, ctxt.Instoffset) - } - o1 = oprrr(ctxt, ABL, int(p.Scond)) - o1 |= (uint32(p.To.Reg) & 15) << 0 - rel := obj.Addrel(ctxt.Cursym) - rel.Off = int32(ctxt.Pc) - rel.Siz = 0 - rel.Type = obj.R_CALLIND - - case 8: /* sll $c,[R],R -> mov (R<<$c),R */ - aclass(ctxt, &p.From) - - o1 = oprrr(ctxt, p.As, int(p.Scond)) - r := int(p.Reg) - if r == 0 { - r = int(p.To.Reg) - } - o1 |= (uint32(r) & 15) << 0 - o1 |= uint32((ctxt.Instoffset & 31) << 7) - o1 |= (uint32(p.To.Reg) & 15) << 12 - - case 9: /* sll R,[R],R -> mov (R< lr */ - aclass(ctxt, &p.From) - - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o1 = olr(ctxt, int32(ctxt.Instoffset), r, int(p.To.Reg), int(p.Scond)) - if p.As != AMOVW { - o1 |= 1 << 22 - } - - case 30: /* mov/movb/movbu R,L(R) */ - o1 = omvl(ctxt, p, &p.To, REGTMP) - - if o1 == 0 { - break - } - r := int(p.To.Reg) - if r == 0 { - r = int(o.param) - } - o2 = osrr(ctxt, int(p.From.Reg), REGTMP&15, r, int(p.Scond)) - if p.As != AMOVW { - o2 |= 1 << 22 - } - - case 31: /* mov/movbu L(R),R -> lr[b] */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - r := int(p.From.Reg) - if r == 0 { - r = int(o.param) - } - o2 = olrr(ctxt, REGTMP&15, r, int(p.To.Reg), int(p.Scond)) - if p.As == AMOVBU || p.As == AMOVBS || p.As == AMOVB { - o2 |= 1 << 22 - } - - case 34: /* mov $lacon,R */ - o1 = omvl(ctxt, p, &p.From, REGTMP) - - if o1 == 0 { - break - } - - o2 = oprrr(ctxt, AADD, int(p.Scond)) - o2 |= REGTMP & 15 - r := int(p.From.Reg) - if r == 0 { - r = int(o.pa