mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-19 02:35:46 -04:00
dep: Add vixl (AArch32/64 assembler)
This commit is contained in:
27923
dep/vixl/src/aarch32/assembler-aarch32.cc
Normal file
27923
dep/vixl/src/aarch32/assembler-aarch32.cc
Normal file
File diff suppressed because it is too large
Load Diff
855
dep/vixl/src/aarch32/constants-aarch32.cc
Normal file
855
dep/vixl/src/aarch32/constants-aarch32.cc
Normal file
@ -0,0 +1,855 @@
|
||||
// Copyright 2016, VIXL authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of ARM Limited nor the names of its contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "aarch32/constants-aarch32.h"
|
||||
#include "utils-vixl.h"
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch32 {
|
||||
|
||||
// Start of generated code.
|
||||
const char* ToCString(InstructionType type) {
|
||||
switch (type) {
|
||||
case kAdc:
|
||||
return "adc";
|
||||
case kAdcs:
|
||||
return "adcs";
|
||||
case kAdd:
|
||||
return "add";
|
||||
case kAdds:
|
||||
return "adds";
|
||||
case kAddw:
|
||||
return "addw";
|
||||
case kAdr:
|
||||
return "adr";
|
||||
case kAnd:
|
||||
return "and";
|
||||
case kAnds:
|
||||
return "ands";
|
||||
case kAsr:
|
||||
return "asr";
|
||||
case kAsrs:
|
||||
return "asrs";
|
||||
case kB:
|
||||
return "b";
|
||||
case kBfc:
|
||||
return "bfc";
|
||||
case kBfi:
|
||||
return "bfi";
|
||||
case kBic:
|
||||
return "bic";
|
||||
case kBics:
|
||||
return "bics";
|
||||
case kBkpt:
|
||||
return "bkpt";
|
||||
case kBl:
|
||||
return "bl";
|
||||
case kBlx:
|
||||
return "blx";
|
||||
case kBx:
|
||||
return "bx";
|
||||
case kBxj:
|
||||
return "bxj";
|
||||
case kCbnz:
|
||||
return "cbnz";
|
||||
case kCbz:
|
||||
return "cbz";
|
||||
case kClrex:
|
||||
return "clrex";
|
||||
case kClz:
|
||||
return "clz";
|
||||
case kCmn:
|
||||
return "cmn";
|
||||
case kCmp:
|
||||
return "cmp";
|
||||
case kCrc32b:
|
||||
return "crc32b";
|
||||
case kCrc32cb:
|
||||
return "crc32cb";
|
||||
case kCrc32ch:
|
||||
return "crc32ch";
|
||||
case kCrc32cw:
|
||||
return "crc32cw";
|
||||
case kCrc32h:
|
||||
return "crc32h";
|
||||
case kCrc32w:
|
||||
return "crc32w";
|
||||
case kDmb:
|
||||
return "dmb";
|
||||
case kDsb:
|
||||
return "dsb";
|
||||
case kEor:
|
||||
return "eor";
|
||||
case kEors:
|
||||
return "eors";
|
||||
case kFldmdbx:
|
||||
return "fldmdbx";
|
||||
case kFldmiax:
|
||||
return "fldmiax";
|
||||
case kFstmdbx:
|
||||
return "fstmdbx";
|
||||
case kFstmiax:
|
||||
return "fstmiax";
|
||||
case kHlt:
|
||||
return "hlt";
|
||||
case kHvc:
|
||||
return "hvc";
|
||||
case kIsb:
|
||||
return "isb";
|
||||
case kIt:
|
||||
return "it";
|
||||
case kLda:
|
||||
return "lda";
|
||||
case kLdab:
|
||||
return "ldab";
|
||||
case kLdaex:
|
||||
return "ldaex";
|
||||
case kLdaexb:
|
||||
return "ldaexb";
|
||||
case kLdaexd:
|
||||
return "ldaexd";
|
||||
case kLdaexh:
|
||||
return "ldaexh";
|
||||
case kLdah:
|
||||
return "ldah";
|
||||
case kLdm:
|
||||
return "ldm";
|
||||
case kLdmda:
|
||||
return "ldmda";
|
||||
case kLdmdb:
|
||||
return "ldmdb";
|
||||
case kLdmea:
|
||||
return "ldmea";
|
||||
case kLdmed:
|
||||
return "ldmed";
|
||||
case kLdmfa:
|
||||
return "ldmfa";
|
||||
case kLdmfd:
|
||||
return "ldmfd";
|
||||
case kLdmib:
|
||||
return "ldmib";
|
||||
case kLdr:
|
||||
return "ldr";
|
||||
case kLdrb:
|
||||
return "ldrb";
|
||||
case kLdrd:
|
||||
return "ldrd";
|
||||
case kLdrex:
|
||||
return "ldrex";
|
||||
case kLdrexb:
|
||||
return "ldrexb";
|
||||
case kLdrexd:
|
||||
return "ldrexd";
|
||||
case kLdrexh:
|
||||
return "ldrexh";
|
||||
case kLdrh:
|
||||
return "ldrh";
|
||||
case kLdrsb:
|
||||
return "ldrsb";
|
||||
case kLdrsh:
|
||||
return "ldrsh";
|
||||
case kLsl:
|
||||
return "lsl";
|
||||
case kLsls:
|
||||
return "lsls";
|
||||
case kLsr:
|
||||
return "lsr";
|
||||
case kLsrs:
|
||||
return "lsrs";
|
||||
case kMla:
|
||||
return "mla";
|
||||
case kMlas:
|
||||
return "mlas";
|
||||
case kMls:
|
||||
return "mls";
|
||||
case kMov:
|
||||
return "mov";
|
||||
case kMovs:
|
||||
return "movs";
|
||||
case kMovt:
|
||||
return "movt";
|
||||
case kMovw:
|
||||
return "movw";
|
||||
case kMrs:
|
||||
return "mrs";
|
||||
case kMsr:
|
||||
return "msr";
|
||||
case kMul:
|
||||
return "mul";
|
||||
case kMuls:
|
||||
return "muls";
|
||||
case kMvn:
|
||||
return "mvn";
|
||||
case kMvns:
|
||||
return "mvns";
|
||||
case kNop:
|
||||
return "nop";
|
||||
case kOrn:
|
||||
return "orn";
|
||||
case kOrns:
|
||||
return "orns";
|
||||
case kOrr:
|
||||
return "orr";
|
||||
case kOrrs:
|
||||
return "orrs";
|
||||
case kPkhbt:
|
||||
return "pkhbt";
|
||||
case kPkhtb:
|
||||
return "pkhtb";
|
||||
case kPld:
|
||||
return "pld";
|
||||
case kPldw:
|
||||
return "pldw";
|
||||
case kPli:
|
||||
return "pli";
|
||||
case kPop:
|
||||
return "pop";
|
||||
case kPush:
|
||||
return "push";
|
||||
case kQadd:
|
||||
return "qadd";
|
||||
case kQadd16:
|
||||
return "qadd16";
|
||||
case kQadd8:
|
||||
return "qadd8";
|
||||
case kQasx:
|
||||
return "qasx";
|
||||
case kQdadd:
|
||||
return "qdadd";
|
||||
case kQdsub:
|
||||
return "qdsub";
|
||||
case kQsax:
|
||||
return "qsax";
|
||||
case kQsub:
|
||||
return "qsub";
|
||||
case kQsub16:
|
||||
return "qsub16";
|
||||
case kQsub8:
|
||||
return "qsub8";
|
||||
case kRbit:
|
||||
return "rbit";
|
||||
case kRev:
|
||||
return "rev";
|
||||
case kRev16:
|
||||
return "rev16";
|
||||
case kRevsh:
|
||||
return "revsh";
|
||||
case kRor:
|
||||
return "ror";
|
||||
case kRors:
|
||||
return "rors";
|
||||
case kRrx:
|
||||
return "rrx";
|
||||
case kRrxs:
|
||||
return "rrxs";
|
||||
case kRsb:
|
||||
return "rsb";
|
||||
case kRsbs:
|
||||
return "rsbs";
|
||||
case kRsc:
|
||||
return "rsc";
|
||||
case kRscs:
|
||||
return "rscs";
|
||||
case kSadd16:
|
||||
return "sadd16";
|
||||
case kSadd8:
|
||||
return "sadd8";
|
||||
case kSasx:
|
||||
return "sasx";
|
||||
case kSbc:
|
||||
return "sbc";
|
||||
case kSbcs:
|
||||
return "sbcs";
|
||||
case kSbfx:
|
||||
return "sbfx";
|
||||
case kSdiv:
|
||||
return "sdiv";
|
||||
case kSel:
|
||||
return "sel";
|
||||
case kShadd16:
|
||||
return "shadd16";
|
||||
case kShadd8:
|
||||
return "shadd8";
|
||||
case kShasx:
|
||||
return "shasx";
|
||||
case kShsax:
|
||||
return "shsax";
|
||||
case kShsub16:
|
||||
return "shsub16";
|
||||
case kShsub8:
|
||||
return "shsub8";
|
||||
case kSmlabb:
|
||||
return "smlabb";
|
||||
case kSmlabt:
|
||||
return "smlabt";
|
||||
case kSmlad:
|
||||
return "smlad";
|
||||
case kSmladx:
|
||||
return "smladx";
|
||||
case kSmlal:
|
||||
return "smlal";
|
||||
case kSmlalbb:
|
||||
return "smlalbb";
|
||||
case kSmlalbt:
|
||||
return "smlalbt";
|
||||
case kSmlald:
|
||||
return "smlald";
|
||||
case kSmlaldx:
|
||||
return "smlaldx";
|
||||
case kSmlals:
|
||||
return "smlals";
|
||||
case kSmlaltb:
|
||||
return "smlaltb";
|
||||
case kSmlaltt:
|
||||
return "smlaltt";
|
||||
case kSmlatb:
|
||||
return "smlatb";
|
||||
case kSmlatt:
|
||||
return "smlatt";
|
||||
case kSmlawb:
|
||||
return "smlawb";
|
||||
case kSmlawt:
|
||||
return "smlawt";
|
||||
case kSmlsd:
|
||||
return "smlsd";
|
||||
case kSmlsdx:
|
||||
return "smlsdx";
|
||||
case kSmlsld:
|
||||
return "smlsld";
|
||||
case kSmlsldx:
|
||||
return "smlsldx";
|
||||
case kSmmla:
|
||||
return "smmla";
|
||||
case kSmmlar:
|
||||
return "smmlar";
|
||||
case kSmmls:
|
||||
return "smmls";
|
||||
case kSmmlsr:
|
||||
return "smmlsr";
|
||||
case kSmmul:
|
||||
return "smmul";
|
||||
case kSmmulr:
|
||||
return "smmulr";
|
||||
case kSmuad:
|
||||
return "smuad";
|
||||
case kSmuadx:
|
||||
return "smuadx";
|
||||
case kSmulbb:
|
||||
return "smulbb";
|
||||
case kSmulbt:
|
||||
return "smulbt";
|
||||
case kSmull:
|
||||
return "smull";
|
||||
case kSmulls:
|
||||
return "smulls";
|
||||
case kSmultb:
|
||||
return "smultb";
|
||||
case kSmultt:
|
||||
return "smultt";
|
||||
case kSmulwb:
|
||||
return "smulwb";
|
||||
case kSmulwt:
|
||||
return "smulwt";
|
||||
case kSmusd:
|
||||
return "smusd";
|
||||
case kSmusdx:
|
||||
return "smusdx";
|
||||
case kSsat:
|
||||
return "ssat";
|
||||
case kSsat16:
|
||||
return "ssat16";
|
||||
case kSsax:
|
||||
return "ssax";
|
||||
case kSsub16:
|
||||
return "ssub16";
|
||||
case kSsub8:
|
||||
return "ssub8";
|
||||
case kStl:
|
||||
return "stl";
|
||||
case kStlb:
|
||||
return "stlb";
|
||||
case kStlex:
|
||||
return "stlex";
|
||||
case kStlexb:
|
||||
return "stlexb";
|
||||
case kStlexd:
|
||||
return "stlexd";
|
||||
case kStlexh:
|
||||
return "stlexh";
|
||||
case kStlh:
|
||||
return "stlh";
|
||||
case kStm:
|
||||
return "stm";
|
||||
case kStmda:
|
||||
return "stmda";
|
||||
case kStmdb:
|
||||
return "stmdb";
|
||||
case kStmea:
|
||||
return "stmea";
|
||||
case kStmed:
|
||||
return "stmed";
|
||||
case kStmfa:
|
||||
return "stmfa";
|
||||
case kStmfd:
|
||||
return "stmfd";
|
||||
case kStmib:
|
||||
return "stmib";
|
||||
case kStr:
|
||||
return "str";
|
||||
case kStrb:
|
||||
return "strb";
|
||||
case kStrd:
|
||||
return "strd";
|
||||
case kStrex:
|
||||
return "strex";
|
||||
case kStrexb:
|
||||
return "strexb";
|
||||
case kStrexd:
|
||||
return "strexd";
|
||||
case kStrexh:
|
||||
return "strexh";
|
||||
case kStrh:
|
||||
return "strh";
|
||||
case kSub:
|
||||
return "sub";
|
||||
case kSubs:
|
||||
return "subs";
|
||||
case kSubw:
|
||||
return "subw";
|
||||
case kSvc:
|
||||
return "svc";
|
||||
case kSxtab:
|
||||
return "sxtab";
|
||||
case kSxtab16:
|
||||
return "sxtab16";
|
||||
case kSxtah:
|
||||
return "sxtah";
|
||||
case kSxtb:
|
||||
return "sxtb";
|
||||
case kSxtb16:
|
||||
return "sxtb16";
|
||||
case kSxth:
|
||||
return "sxth";
|
||||
case kTbb:
|
||||
return "tbb";
|
||||
case kTbh:
|
||||
return "tbh";
|
||||
case kTeq:
|
||||
return "teq";
|
||||
case kTst:
|
||||
return "tst";
|
||||
case kUadd16:
|
||||
return "uadd16";
|
||||
case kUadd8:
|
||||
return "uadd8";
|
||||
case kUasx:
|
||||
return "uasx";
|
||||
case kUbfx:
|
||||
return "ubfx";
|
||||
case kUdf:
|
||||
return "udf";
|
||||
case kUdiv:
|
||||
return "udiv";
|
||||
case kUhadd16:
|
||||
return "uhadd16";
|
||||
case kUhadd8:
|
||||
return "uhadd8";
|
||||
case kUhasx:
|
||||
return "uhasx";
|
||||
case kUhsax:
|
||||
return "uhsax";
|
||||
case kUhsub16:
|
||||
return "uhsub16";
|
||||
case kUhsub8:
|
||||
return "uhsub8";
|
||||
case kUmaal:
|
||||
return "umaal";
|
||||
case kUmlal:
|
||||
return "umlal";
|
||||
case kUmlals:
|
||||
return "umlals";
|
||||
case kUmull:
|
||||
return "umull";
|
||||
case kUmulls:
|
||||
return "umulls";
|
||||
case kUqadd16:
|
||||
return "uqadd16";
|
||||
case kUqadd8:
|
||||
return "uqadd8";
|
||||
case kUqasx:
|
||||
return "uqasx";
|
||||
case kUqsax:
|
||||
return "uqsax";
|
||||
case kUqsub16:
|
||||
return "uqsub16";
|
||||
case kUqsub8:
|
||||
return "uqsub8";
|
||||
case kUsad8:
|
||||
return "usad8";
|
||||
case kUsada8:
|
||||
return "usada8";
|
||||
case kUsat:
|
||||
return "usat";
|
||||
case kUsat16:
|
||||
return "usat16";
|
||||
case kUsax:
|
||||
return "usax";
|
||||
case kUsub16:
|
||||
return "usub16";
|
||||
case kUsub8:
|
||||
return "usub8";
|
||||
case kUxtab:
|
||||
return "uxtab";
|
||||
case kUxtab16:
|
||||
return "uxtab16";
|
||||
case kUxtah:
|
||||
return "uxtah";
|
||||
case kUxtb:
|
||||
return "uxtb";
|
||||
case kUxtb16:
|
||||
return "uxtb16";
|
||||
case kUxth:
|
||||
return "uxth";
|
||||
case kVaba:
|
||||
return "vaba";
|
||||
case kVabal:
|
||||
return "vabal";
|
||||
case kVabd:
|
||||
return "vabd";
|
||||
case kVabdl:
|
||||
return "vabdl";
|
||||
case kVabs:
|
||||
return "vabs";
|
||||
case kVacge:
|
||||
return "vacge";
|
||||
case kVacgt:
|
||||
return "vacgt";
|
||||
case kVacle:
|
||||
return "vacle";
|
||||
case kVaclt:
|
||||
return "vaclt";
|
||||
case kVadd:
|
||||
return "vadd";
|
||||
case kVaddhn:
|
||||
return "vaddhn";
|
||||
case kVaddl:
|
||||
return "vaddl";
|
||||
case kVaddw:
|
||||
return "vaddw";
|
||||
case kVand:
|
||||
return "vand";
|
||||
case kVbic:
|
||||
return "vbic";
|
||||
case kVbif:
|
||||
return "vbif";
|
||||
case kVbit:
|
||||
return "vbit";
|
||||
case kVbsl:
|
||||
return "vbsl";
|
||||
case kVceq:
|
||||
return "vceq";
|
||||
case kVcge:
|
||||
return "vcge";
|
||||
case kVcgt:
|
||||
return "vcgt";
|
||||
case kVcle:
|
||||
return "vcle";
|
||||
case kVcls:
|
||||
return "vcls";
|
||||
case kVclt:
|
||||
return "vclt";
|
||||
case kVclz:
|
||||
return "vclz";
|
||||
case kVcmp:
|
||||
return "vcmp";
|
||||
case kVcmpe:
|
||||
return "vcmpe";
|
||||
case kVcnt:
|
||||
return "vcnt";
|
||||
case kVcvt:
|
||||
return "vcvt";
|
||||
case kVcvta:
|
||||
return "vcvta";
|
||||
case kVcvtb:
|
||||
return "vcvtb";
|
||||
case kVcvtm:
|
||||
return "vcvtm";
|
||||
case kVcvtn:
|
||||
return "vcvtn";
|
||||
case kVcvtp:
|
||||
return "vcvtp";
|
||||
case kVcvtr:
|
||||
return "vcvtr";
|
||||
case kVcvtt:
|
||||
return "vcvtt";
|
||||
case kVdiv:
|
||||
return "vdiv";
|
||||
case kVdup:
|
||||
return "vdup";
|
||||
case kVeor:
|
||||
return "veor";
|
||||
case kVext:
|
||||
return "vext";
|
||||
case kVfma:
|
||||
return "vfma";
|
||||
case kVfms:
|
||||
return "vfms";
|
||||
case kVfnma:
|
||||
return "vfnma";
|
||||
case kVfnms:
|
||||
return "vfnms";
|
||||
case kVhadd:
|
||||
return "vhadd";
|
||||
case kVhsub:
|
||||
return "vhsub";
|
||||
case kVld1:
|
||||
return "vld1";
|
||||
case kVld2:
|
||||
return "vld2";
|
||||
case kVld3:
|
||||
return "vld3";
|
||||
case kVld4:
|
||||
return "vld4";
|
||||
case kVldm:
|
||||
return "vldm";
|
||||
case kVldmdb:
|
||||
return "vldmdb";
|
||||
case kVldmia:
|
||||
return "vldmia";
|
||||
case kVldr:
|
||||
return "vldr";
|
||||
case kVmax:
|
||||
return "vmax";
|
||||
case kVmaxnm:
|
||||
return "vmaxnm";
|
||||
case kVmin:
|
||||
return "vmin";
|
||||
case kVminnm:
|
||||
return "vminnm";
|
||||
case kVmla:
|
||||
return "vmla";
|
||||
case kVmlal:
|
||||
return "vmlal";
|
||||
case kVmls:
|
||||
return "vmls";
|
||||
case kVmlsl:
|
||||
return "vmlsl";
|
||||
case kVmov:
|
||||
return "vmov";
|
||||
case kVmovl:
|
||||
return "vmovl";
|
||||
case kVmovn:
|
||||
return "vmovn";
|
||||
case kVmrs:
|
||||
return "vmrs";
|
||||
case kVmsr:
|
||||
return "vmsr";
|
||||
case kVmul:
|
||||
return "vmul";
|
||||
case kVmull:
|
||||
return "vmull";
|
||||
case kVmvn:
|
||||
return "vmvn";
|
||||
case kVneg:
|
||||
return "vneg";
|
||||
case kVnmla:
|
||||
return "vnmla";
|
||||
case kVnmls:
|
||||
return "vnmls";
|
||||
case kVnmul:
|
||||
return "vnmul";
|
||||
case kVorn:
|
||||
return "vorn";
|
||||
case kVorr:
|
||||
return "vorr";
|
||||
case kVpadal:
|
||||
return "vpadal";
|
||||
case kVpadd:
|
||||
return "vpadd";
|
||||
case kVpaddl:
|
||||
return "vpaddl";
|
||||
case kVpmax:
|
||||
return "vpmax";
|
||||
case kVpmin:
|
||||
return "vpmin";
|
||||
case kVpop:
|
||||
return "vpop";
|
||||
case kVpush:
|
||||
return "vpush";
|
||||
case kVqabs:
|
||||
return "vqabs";
|
||||
case kVqadd:
|
||||
return "vqadd";
|
||||
case kVqdmlal:
|
||||
return "vqdmlal";
|
||||
case kVqdmlsl:
|
||||
return "vqdmlsl";
|
||||
case kVqdmulh:
|
||||
return "vqdmulh";
|
||||
case kVqdmull:
|
||||
return "vqdmull";
|
||||
case kVqmovn:
|
||||
return "vqmovn";
|
||||
case kVqmovun:
|
||||
return "vqmovun";
|
||||
case kVqneg:
|
||||
return "vqneg";
|
||||
case kVqrdmulh:
|
||||
return "vqrdmulh";
|
||||
case kVqrshl:
|
||||
return "vqrshl";
|
||||
case kVqrshrn:
|
||||
return "vqrshrn";
|
||||
case kVqrshrun:
|
||||
return "vqrshrun";
|
||||
case kVqshl:
|
||||
return "vqshl";
|
||||
case kVqshlu:
|
||||
return "vqshlu";
|
||||
case kVqshrn:
|
||||
return "vqshrn";
|
||||
case kVqshrun:
|
||||
return "vqshrun";
|
||||
case kVqsub:
|
||||
return "vqsub";
|
||||
case kVraddhn:
|
||||
return "vraddhn";
|
||||
case kVrecpe:
|
||||
return "vrecpe";
|
||||
case kVrecps:
|
||||
return "vrecps";
|
||||
case kVrev16:
|
||||
return "vrev16";
|
||||
case kVrev32:
|
||||
return "vrev32";
|
||||
case kVrev64:
|
||||
return "vrev64";
|
||||
case kVrhadd:
|
||||
return "vrhadd";
|
||||
case kVrinta:
|
||||
return "vrinta";
|
||||
case kVrintm:
|
||||
return "vrintm";
|
||||
case kVrintn:
|
||||
return "vrintn";
|
||||
case kVrintp:
|
||||
return "vrintp";
|
||||
case kVrintr:
|
||||
return "vrintr";
|
||||
case kVrintx:
|
||||
return "vrintx";
|
||||
case kVrintz:
|
||||
return "vrintz";
|
||||
case kVrshl:
|
||||
return "vrshl";
|
||||
case kVrshr:
|
||||
return "vrshr";
|
||||
case kVrshrn:
|
||||
return "vrshrn";
|
||||
case kVrsqrte:
|
||||
return "vrsqrte";
|
||||
case kVrsqrts:
|
||||
return "vrsqrts";
|
||||
case kVrsra:
|
||||
return "vrsra";
|
||||
case kVrsubhn:
|
||||
return "vrsubhn";
|
||||
case kVseleq:
|
||||
return "vseleq";
|
||||
case kVselge:
|
||||
return "vselge";
|
||||
case kVselgt:
|
||||
return "vselgt";
|
||||
case kVselvs:
|
||||
return "vselvs";
|
||||
case kVshl:
|
||||
return "vshl";
|
||||
case kVshll:
|
||||
return "vshll";
|
||||
case kVshr:
|
||||
return "vshr";
|
||||
case kVshrn:
|
||||
return "vshrn";
|
||||
case kVsli:
|
||||
return "vsli";
|
||||
case kVsqrt:
|
||||
return "vsqrt";
|
||||
case kVsra:
|
||||
return "vsra";
|
||||
case kVsri:
|
||||
return "vsri";
|
||||
case kVst1:
|
||||
return "vst1";
|
||||
case kVst2:
|
||||
return "vst2";
|
||||
case kVst3:
|
||||
return "vst3";
|
||||
case kVst4:
|
||||
return "vst4";
|
||||
case kVstm:
|
||||
return "vstm";
|
||||
case kVstmdb:
|
||||
return "vstmdb";
|
||||
case kVstmia:
|
||||
return "vstmia";
|
||||
case kVstr:
|
||||
return "vstr";
|
||||
case kVsub:
|
||||
return "vsub";
|
||||
case kVsubhn:
|
||||
return "vsubhn";
|
||||
case kVsubl:
|
||||
return "vsubl";
|
||||
case kVsubw:
|
||||
return "vsubw";
|
||||
case kVswp:
|
||||
return "vswp";
|
||||
case kVtbl:
|
||||
return "vtbl";
|
||||
case kVtbx:
|
||||
return "vtbx";
|
||||
case kVtrn:
|
||||
return "vtrn";
|
||||
case kVtst:
|
||||
return "vtst";
|
||||
case kVuzp:
|
||||
return "vuzp";
|
||||
case kVzip:
|
||||
return "vzip";
|
||||
case kYield:
|
||||
return "yield";
|
||||
case kUndefInstructionType:
|
||||
VIXL_UNREACHABLE();
|
||||
return "";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "";
|
||||
} // NOLINT(readability/fn_size)
|
||||
// End of generated code.
|
||||
|
||||
} // namespace aarch32
|
||||
} // namespace vixl
|
67276
dep/vixl/src/aarch32/disasm-aarch32.cc
Normal file
67276
dep/vixl/src/aarch32/disasm-aarch32.cc
Normal file
File diff suppressed because it is too large
Load Diff
742
dep/vixl/src/aarch32/instructions-aarch32.cc
Normal file
742
dep/vixl/src/aarch32/instructions-aarch32.cc
Normal file
@ -0,0 +1,742 @@
|
||||
// Copyright 2017, VIXL authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of ARM Limited nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
}
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include "utils-vixl.h"
|
||||
#include "aarch32/constants-aarch32.h"
|
||||
#include "aarch32/instructions-aarch32.h"
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch32 {
|
||||
|
||||
|
||||
bool Shift::IsValidAmount(uint32_t amount) const {
|
||||
switch (GetType()) {
|
||||
case LSL:
|
||||
return amount <= 31;
|
||||
case ROR:
|
||||
return (amount > 0) && (amount <= 31);
|
||||
case LSR:
|
||||
case ASR:
|
||||
return (amount > 0) && (amount <= 32);
|
||||
case RRX:
|
||||
return amount == 0;
|
||||
default:
|
||||
VIXL_UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Register reg) {
|
||||
switch (reg.GetCode()) {
|
||||
case 12:
|
||||
return os << "ip";
|
||||
case 13:
|
||||
return os << "sp";
|
||||
case 14:
|
||||
return os << "lr";
|
||||
case 15:
|
||||
return os << "pc";
|
||||
default:
|
||||
return os << "r" << reg.GetCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SRegister VRegister::S() const {
|
||||
VIXL_ASSERT(GetType() == kSRegister);
|
||||
return SRegister(GetCode());
|
||||
}
|
||||
|
||||
|
||||
DRegister VRegister::D() const {
|
||||
VIXL_ASSERT(GetType() == kDRegister);
|
||||
return DRegister(GetCode());
|
||||
}
|
||||
|
||||
|
||||
QRegister VRegister::Q() const {
|
||||
VIXL_ASSERT(GetType() == kQRegister);
|
||||
return QRegister(GetCode());
|
||||
}
|
||||
|
||||
|
||||
Register RegisterList::GetFirstAvailableRegister() const {
|
||||
for (uint32_t i = 0; i < kNumberOfRegisters; i++) {
|
||||
if (((list_ >> i) & 1) != 0) return Register(i);
|
||||
}
|
||||
return Register();
|
||||
}
|
||||
|
||||
|
||||
std::ostream& PrintRegisterList(std::ostream& os, // NOLINT(runtime/references)
|
||||
uint32_t list) {
|
||||
os << "{";
|
||||
bool first = true;
|
||||
int code = 0;
|
||||
while (list != 0) {
|
||||
if ((list & 1) != 0) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
os << ",";
|
||||
}
|
||||
os << Register(code);
|
||||
}
|
||||
list >>= 1;
|
||||
code++;
|
||||
}
|
||||
os << "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, RegisterList registers) {
|
||||
return PrintRegisterList(os, registers.GetList());
|
||||
}
|
||||
|
||||
|
||||
QRegister VRegisterList::GetFirstAvailableQRegister() const {
|
||||
for (uint32_t i = 0; i < kNumberOfQRegisters; i++) {
|
||||
if (((list_ >> (i * 4)) & 0xf) == 0xf) return QRegister(i);
|
||||
}
|
||||
return QRegister();
|
||||
}
|
||||
|
||||
|
||||
DRegister VRegisterList::GetFirstAvailableDRegister() const {
|
||||
for (uint32_t i = 0; i < kMaxNumberOfDRegisters; i++) {
|
||||
if (((list_ >> (i * 2)) & 0x3) == 0x3) return DRegister(i);
|
||||
}
|
||||
return DRegister();
|
||||
}
|
||||
|
||||
|
||||
SRegister VRegisterList::GetFirstAvailableSRegister() const {
|
||||
for (uint32_t i = 0; i < kNumberOfSRegisters; i++) {
|
||||
if (((list_ >> i) & 0x1) != 0) return SRegister(i);
|
||||
}
|
||||
return SRegister();
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, SRegisterList reglist) {
|
||||
SRegister first = reglist.GetFirstSRegister();
|
||||
SRegister last = reglist.GetLastSRegister();
|
||||
if (first.Is(last))
|
||||
os << "{" << first << "}";
|
||||
else
|
||||
os << "{" << first << "-" << last << "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, DRegisterList reglist) {
|
||||
DRegister first = reglist.GetFirstDRegister();
|
||||
DRegister last = reglist.GetLastDRegister();
|
||||
if (first.Is(last))
|
||||
os << "{" << first << "}";
|
||||
else
|
||||
os << "{" << first << "-" << last << "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, NeonRegisterList nreglist) {
|
||||
DRegister first = nreglist.GetFirstDRegister();
|
||||
int increment = nreglist.IsSingleSpaced() ? 1 : 2;
|
||||
int count =
|
||||
nreglist.GetLastDRegister().GetCode() - first.GetCode() + increment;
|
||||
if (count < 0) count += kMaxNumberOfDRegisters;
|
||||
os << "{";
|
||||
bool first_displayed = false;
|
||||
for (;;) {
|
||||
if (first_displayed) {
|
||||
os << ",";
|
||||
} else {
|
||||
first_displayed = true;
|
||||
}
|
||||
os << first;
|
||||
if (nreglist.IsTransferOneLane()) {
|
||||
os << "[" << nreglist.GetTransferLane() << "]";
|
||||
} else if (nreglist.IsTransferAllLanes()) {
|
||||
os << "[]";
|
||||
}
|
||||
count -= increment;
|
||||
if (count <= 0) break;
|
||||
unsigned next = first.GetCode() + increment;
|
||||
if (next >= kMaxNumberOfDRegisters) next -= kMaxNumberOfDRegisters;
|
||||
first = DRegister(next);
|
||||
}
|
||||
os << "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
const char* SpecialRegister::GetName() const {
|
||||
switch (reg_) {
|
||||
case APSR:
|
||||
return "APSR";
|
||||
case SPSR:
|
||||
return "SPSR";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "??";
|
||||
}
|
||||
|
||||
|
||||
const char* MaskedSpecialRegister::GetName() const {
|
||||
switch (reg_) {
|
||||
case APSR_nzcvq:
|
||||
return "APSR_nzcvq";
|
||||
case APSR_g:
|
||||
return "APSR_g";
|
||||
case APSR_nzcvqg:
|
||||
return "APSR_nzcvqg";
|
||||
case CPSR_c:
|
||||
return "CPSR_c";
|
||||
case CPSR_x:
|
||||
return "CPSR_x";
|
||||
case CPSR_xc:
|
||||
return "CPSR_xc";
|
||||
case CPSR_sc:
|
||||
return "CPSR_sc";
|
||||
case CPSR_sx:
|
||||
return "CPSR_sx";
|
||||
case CPSR_sxc:
|
||||
return "CPSR_sxc";
|
||||
case CPSR_fc:
|
||||
return "CPSR_fc";
|
||||
case CPSR_fx:
|
||||
return "CPSR_fx";
|
||||
case CPSR_fxc:
|
||||
return "CPSR_fxc";
|
||||
case CPSR_fsc:
|
||||
return "CPSR_fsc";
|
||||
case CPSR_fsx:
|
||||
return "CPSR_fsx";
|
||||
case CPSR_fsxc:
|
||||
return "CPSR_fsxc";
|
||||
case SPSR_c:
|
||||
return "SPSR_c";
|
||||
case SPSR_x:
|
||||
return "SPSR_x";
|
||||
case SPSR_xc:
|
||||
return "SPSR_xc";
|
||||
case SPSR_s:
|
||||
return "SPSR_s";
|
||||
case SPSR_sc:
|
||||
return "SPSR_sc";
|
||||
case SPSR_sx:
|
||||
return "SPSR_sx";
|
||||
case SPSR_sxc:
|
||||
return "SPSR_sxc";
|
||||
case SPSR_f:
|
||||
return "SPSR_f";
|
||||
case SPSR_fc:
|
||||
return "SPSR_fc";
|
||||
case SPSR_fx:
|
||||
return "SPSR_fx";
|
||||
case SPSR_fxc:
|
||||
return "SPSR_fxc";
|
||||
case SPSR_fs:
|
||||
return "SPSR_fs";
|
||||
case SPSR_fsc:
|
||||
return "SPSR_fsc";
|
||||
case SPSR_fsx:
|
||||
return "SPSR_fsx";
|
||||
case SPSR_fsxc:
|
||||
return "SPSR_fsxc";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "??";
|
||||
}
|
||||
|
||||
|
||||
const char* BankedRegister::GetName() const {
|
||||
switch (reg_) {
|
||||
case R8_usr:
|
||||
return "R8_usr";
|
||||
case R9_usr:
|
||||
return "R9_usr";
|
||||
case R10_usr:
|
||||
return "R10_usr";
|
||||
case R11_usr:
|
||||
return "R11_usr";
|
||||
case R12_usr:
|
||||
return "R12_usr";
|
||||
case SP_usr:
|
||||
return "SP_usr";
|
||||
case LR_usr:
|
||||
return "LR_usr";
|
||||
case R8_fiq:
|
||||
return "R8_fiq";
|
||||
case R9_fiq:
|
||||
return "R9_fiq";
|
||||
case R10_fiq:
|
||||
return "R10_fiq";
|
||||
case R11_fiq:
|
||||
return "R11_fiq";
|
||||
case R12_fiq:
|
||||
return "R12_fiq";
|
||||
case SP_fiq:
|
||||
return "SP_fiq";
|
||||
case LR_fiq:
|
||||
return "LR_fiq";
|
||||
case LR_irq:
|
||||
return "LR_irq";
|
||||
case SP_irq:
|
||||
return "SP_irq";
|
||||
case LR_svc:
|
||||
return "LR_svc";
|
||||
case SP_svc:
|
||||
return "SP_svc";
|
||||
case LR_abt:
|
||||
return "LR_abt";
|
||||
case SP_abt:
|
||||
return "SP_abt";
|
||||
case LR_und:
|
||||
return "LR_und";
|
||||
case SP_und:
|
||||
return "SP_und";
|
||||
case LR_mon:
|
||||
return "LR_mon";
|
||||
case SP_mon:
|
||||
return "SP_mon";
|
||||
case ELR_hyp:
|
||||
return "ELR_hyp";
|
||||
case SP_hyp:
|
||||
return "SP_hyp";
|
||||
case SPSR_fiq:
|
||||
return "SPSR_fiq";
|
||||
case SPSR_irq:
|
||||
return "SPSR_irq";
|
||||
case SPSR_svc:
|
||||
return "SPSR_svc";
|
||||
case SPSR_abt:
|
||||
return "SPSR_abt";
|
||||
case SPSR_und:
|
||||
return "SPSR_und";
|
||||
case SPSR_mon:
|
||||
return "SPSR_mon";
|
||||
case SPSR_hyp:
|
||||
return "SPSR_hyp";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "??";
|
||||
}
|
||||
|
||||
const char* SpecialFPRegister::GetName() const {
|
||||
switch (reg_) {
|
||||
case FPSID:
|
||||
return "FPSID";
|
||||
case FPSCR:
|
||||
return "FPSCR";
|
||||
case MVFR2:
|
||||
return "MVFR2";
|
||||
case MVFR1:
|
||||
return "MVFR1";
|
||||
case MVFR0:
|
||||
return "MVFR0";
|
||||
case FPEXC:
|
||||
return "FPEXC";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "??";
|
||||
}
|
||||
|
||||
|
||||
const char* Condition::GetName() const {
|
||||
switch (condition_) {
|
||||
case eq:
|
||||
return "eq";
|
||||
case ne:
|
||||
return "ne";
|
||||
case cs:
|
||||
return "cs";
|
||||
case cc:
|
||||
return "cc";
|
||||
case mi:
|
||||
return "mi";
|
||||
case pl:
|
||||
return "pl";
|
||||
case vs:
|
||||
return "vs";
|
||||
case vc:
|
||||
return "vc";
|
||||
case hi:
|
||||
return "hi";
|
||||
case ls:
|
||||
return "ls";
|
||||
case ge:
|
||||
return "ge";
|
||||
case lt:
|
||||
return "lt";
|
||||
case gt:
|
||||
return "gt";
|
||||
case le:
|
||||
return "le";
|
||||
case al:
|
||||
return "";
|
||||
case Condition::kNone:
|
||||
return "";
|
||||
}
|
||||
return "<und>";
|
||||
}
|
||||
|
||||
|
||||
const char* Shift::GetName() const {
|
||||
switch (shift_) {
|
||||
case LSL:
|
||||
return "lsl";
|
||||
case LSR:
|
||||
return "lsr";
|
||||
case ASR:
|
||||
return "asr";
|
||||
case ROR:
|
||||
return "ror";
|
||||
case RRX:
|
||||
return "rrx";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "??";
|
||||
}
|
||||
|
||||
|
||||
const char* EncodingSize::GetName() const {
|
||||
switch (size_) {
|
||||
case Best:
|
||||
case Narrow:
|
||||
return "";
|
||||
case Wide:
|
||||
return ".w";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "??";
|
||||
}
|
||||
|
||||
|
||||
const char* DataType::GetName() const {
|
||||
switch (value_) {
|
||||
case kDataTypeValueInvalid:
|
||||
return ".??";
|
||||
case kDataTypeValueNone:
|
||||
return "";
|
||||
case S8:
|
||||
return ".s8";
|
||||
case S16:
|
||||
return ".s16";
|
||||
case S32:
|
||||
return ".s32";
|
||||
case S64:
|
||||
return ".s64";
|
||||
case U8:
|
||||
return ".u8";
|
||||
case U16:
|
||||
return ".u16";
|
||||
case U32:
|
||||
return ".u32";
|
||||
case U64:
|
||||
return ".u64";
|
||||
case F16:
|
||||
return ".f16";
|
||||
case F32:
|
||||
return ".f32";
|
||||
case F64:
|
||||
return ".f64";
|
||||
case I8:
|
||||
return ".i8";
|
||||
case I16:
|
||||
return ".i16";
|
||||
case I32:
|
||||
return ".i32";
|
||||
case I64:
|
||||
return ".i64";
|
||||
case P8:
|
||||
return ".p8";
|
||||
case P64:
|
||||
return ".p64";
|
||||
case Untyped8:
|
||||
return ".8";
|
||||
case Untyped16:
|
||||
return ".16";
|
||||
case Untyped32:
|
||||
return ".32";
|
||||
case Untyped64:
|
||||
return ".64";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return ".??";
|
||||
}
|
||||
|
||||
|
||||
const char* MemoryBarrier::GetName() const {
|
||||
switch (type_) {
|
||||
case OSHLD:
|
||||
return "oshld";
|
||||
case OSHST:
|
||||
return "oshst";
|
||||
case OSH:
|
||||
return "osh";
|
||||
case NSHLD:
|
||||
return "nshld";
|
||||
case NSHST:
|
||||
return "nshst";
|
||||
case NSH:
|
||||
return "nsh";
|
||||
case ISHLD:
|
||||
return "ishld";
|
||||
case ISHST:
|
||||
return "ishst";
|
||||
case ISH:
|
||||
return "ish";
|
||||
case LD:
|
||||
return "ld";
|
||||
case ST:
|
||||
return "st";
|
||||
case SY:
|
||||
return "sy";
|
||||
}
|
||||
switch (static_cast<int>(type_)) {
|
||||
case 0:
|
||||
return "#0x0";
|
||||
case 4:
|
||||
return "#0x4";
|
||||
case 8:
|
||||
return "#0x8";
|
||||
case 0xc:
|
||||
return "#0xc";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "??";
|
||||
}
|
||||
|
||||
|
||||
const char* InterruptFlags::GetName() const {
|
||||
switch (type_) {
|
||||
case F:
|
||||
return "f";
|
||||
case I:
|
||||
return "i";
|
||||
case IF:
|
||||
return "if";
|
||||
case A:
|
||||
return "a";
|
||||
case AF:
|
||||
return "af";
|
||||
case AI:
|
||||
return "ai";
|
||||
case AIF:
|
||||
return "aif";
|
||||
}
|
||||
VIXL_ASSERT(type_ == 0);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
const char* Endianness::GetName() const {
|
||||
switch (type_) {
|
||||
case LE:
|
||||
return "le";
|
||||
case BE:
|
||||
return "be";
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return "??";
|
||||
}
|
||||
|
||||
|
||||
// Constructor used for disassembly.
|
||||
ImmediateShiftOperand::ImmediateShiftOperand(int shift_value, int amount_value)
|
||||
: Shift(shift_value) {
|
||||
switch (shift_value) {
|
||||
case LSL:
|
||||
amount_ = amount_value;
|
||||
break;
|
||||
case LSR:
|
||||
case ASR:
|
||||
amount_ = (amount_value == 0) ? 32 : amount_value;
|
||||
break;
|
||||
case ROR:
|
||||
amount_ = amount_value;
|
||||
if (amount_value == 0) SetType(RRX);
|
||||
break;
|
||||
default:
|
||||
VIXL_UNREACHABLE();
|
||||
SetType(LSL);
|
||||
amount_ = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImmediateT32::ImmediateT32(uint32_t imm) {
|
||||
// 00000000 00000000 00000000 abcdefgh
|
||||
if ((imm & ~0xff) == 0) {
|
||||
SetEncodingValue(imm);
|
||||
return;
|
||||
}
|
||||
if ((imm >> 16) == (imm & 0xffff)) {
|
||||
if ((imm & 0xff00) == 0) {
|
||||
// 00000000 abcdefgh 00000000 abcdefgh
|
||||
SetEncodingValue((imm & 0xff) | (0x1 << 8));
|
||||
return;
|
||||
}
|
||||
if ((imm & 0xff) == 0) {
|
||||
// abcdefgh 00000000 abcdefgh 00000000
|
||||
SetEncodingValue(((imm >> 8) & 0xff) | (0x2 << 8));
|
||||
return;
|
||||
}
|
||||
if (((imm >> 8) & 0xff) == (imm & 0xff)) {
|
||||
// abcdefgh abcdefgh abcdefgh abcdefgh
|
||||
SetEncodingValue((imm & 0xff) | (0x3 << 8));
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int shift = 0; shift < 24; shift++) {
|
||||
uint32_t imm8 = imm >> (24 - shift);
|
||||
uint32_t overflow = imm << (8 + shift);
|
||||
if ((imm8 <= 0xff) && ((imm8 & 0x80) != 0) && (overflow == 0)) {
|
||||
SetEncodingValue(((shift + 8) << 7) | (imm8 & 0x7F));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t ror(uint32_t x, int i) {
|
||||
VIXL_ASSERT((0 < i) && (i < 32));
|
||||
return (x >> i) | (x << (32 - i));
|
||||
}
|
||||
|
||||
|
||||
bool ImmediateT32::IsImmediateT32(uint32_t imm) {
|
||||
/* abcdefgh abcdefgh abcdefgh abcdefgh */
|
||||
if ((imm ^ ror(imm, 8)) == 0) return true;
|
||||
/* 00000000 abcdefgh 00000000 abcdefgh */
|
||||
/* abcdefgh 00000000 abcdefgh 00000000 */
|
||||
if ((imm ^ ror(imm, 16)) == 0 &&
|
||||
(((imm & 0xff00) == 0) || ((imm & 0xff) == 0)))
|
||||
return true;
|
||||
/* isolate least-significant set bit */
|
||||
uint32_t lsb = imm & -imm;
|
||||
/* if imm is less than lsb*256 then it fits, but instead we test imm/256 to
|
||||
* avoid overflow (underflow is always a successful case) */
|
||||
return ((imm >> 8) < lsb);
|
||||
}
|
||||
|
||||
|
||||
uint32_t ImmediateT32::Decode(uint32_t value) {
|
||||
uint32_t base = value & 0xff;
|
||||
switch (value >> 8) {
|
||||
case 0:
|
||||
return base;
|
||||
case 1:
|
||||
return base | (base << 16);
|
||||
case 2:
|
||||
return (base << 8) | (base << 24);
|
||||
case 3:
|
||||
return base | (base << 8) | (base << 16) | (base << 24);
|
||||
default:
|
||||
base |= 0x80;
|
||||
return base << (32 - (value >> 7));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImmediateA32::ImmediateA32(uint32_t imm) {
|
||||
// Deal with rot = 0 first to avoid undefined shift by 32.
|
||||
if (imm <= 0xff) {
|
||||
SetEncodingValue(imm);
|
||||
return;
|
||||
}
|
||||
for (int rot = 2; rot < 32; rot += 2) {
|
||||
uint32_t imm8 = (imm << rot) | (imm >> (32 - rot));
|
||||
if (imm8 <= 0xff) {
|
||||
SetEncodingValue((rot << 7) | imm8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ImmediateA32::IsImmediateA32(uint32_t imm) {
|
||||
/* fast-out */
|
||||
if (imm < 256) return true;
|
||||
/* avoid getting confused by wrapped-around bytes (this transform has no
|
||||
* effect on pass/fail results) */
|
||||
if (imm & 0xff000000) imm = ror(imm, 16);
|
||||
/* copy odd-numbered set bits into even-numbered bits immediately below, so
|
||||
* that the least-significant set bit is always an even bit */
|
||||
imm = imm | ((imm >> 1) & 0x55555555);
|
||||
/* isolate least-significant set bit (always even) */
|
||||
uint32_t lsb = imm & -imm;
|
||||
/* if imm is less than lsb*256 then it fits, but instead we test imm/256 to
|
||||
* avoid overflow (underflow is always a successful case) */
|
||||
return ((imm >> 8) < lsb);
|
||||
}
|
||||
|
||||
|
||||
uint32_t ImmediateA32::Decode(uint32_t value) {
|
||||
int rotation = (value >> 8) * 2;
|
||||
VIXL_ASSERT(rotation >= 0);
|
||||
VIXL_ASSERT(rotation <= 30);
|
||||
value &= 0xff;
|
||||
if (rotation == 0) return value;
|
||||
return (value >> rotation) | (value << (32 - rotation));
|
||||
}
|
||||
|
||||
|
||||
uint32_t TypeEncodingValue(Shift shift) {
|
||||
return shift.IsRRX() ? kRRXEncodedValue : shift.GetValue();
|
||||
}
|
||||
|
||||
|
||||
uint32_t AmountEncodingValue(Shift shift, uint32_t amount) {
|
||||
switch (shift.GetType()) {
|
||||
case LSL:
|
||||
case ROR:
|
||||
return amount;
|
||||
case LSR:
|
||||
case ASR:
|
||||
return amount % 32;
|
||||
case RRX:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace aarch32
|
||||
} // namespace vixl
|
152
dep/vixl/src/aarch32/location-aarch32.cc
Normal file
152
dep/vixl/src/aarch32/location-aarch32.cc
Normal file
@ -0,0 +1,152 @@
|
||||
// Copyright 2017, VIXL authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of ARM Limited nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "location-aarch32.h"
|
||||
|
||||
#include "assembler-aarch32.h"
|
||||
#include "macro-assembler-aarch32.h"
|
||||
|
||||
namespace vixl {
|
||||
|
||||
namespace aarch32 {
|
||||
|
||||
bool Location::Needs16BitPadding(int32_t location) const {
|
||||
if (!HasForwardReferences()) return false;
|
||||
const ForwardRef& last_ref = GetLastForwardReference();
|
||||
int32_t min_location_last_ref = last_ref.GetMinLocation();
|
||||
VIXL_ASSERT(min_location_last_ref - location <= 2);
|
||||
return (min_location_last_ref > location);
|
||||
}
|
||||
|
||||
void Location::ResolveReferences(internal::AssemblerBase* assembler) {
|
||||
// Iterate over references and call EncodeLocationFor on each of them.
|
||||
for (ForwardRefListIterator it(this); !it.Done(); it.Advance()) {
|
||||
const ForwardRef& reference = *it.Current();
|
||||
VIXL_ASSERT(reference.LocationIsEncodable(location_));
|
||||
int32_t from = reference.GetLocation();
|
||||
EncodeLocationFor(assembler, from, reference.op());
|
||||
}
|
||||
forward_.clear();
|
||||
}
|
||||
|
||||
static bool Is16BitEncoding(uint16_t instr) {
|
||||
return instr < (kLowestT32_32Opcode >> 16);
|
||||
}
|
||||
|
||||
void Location::EncodeLocationFor(internal::AssemblerBase* assembler,
|
||||
int32_t from,
|
||||
const Location::EmitOperator* encoder) {
|
||||
if (encoder->IsUsingT32()) {
|
||||
uint16_t* instr_ptr =
|
||||
assembler->GetBuffer()->GetOffsetAddress<uint16_t*>(from);
|
||||
if (Is16BitEncoding(instr_ptr[0])) {
|
||||
// The Encode methods always deals with uint32_t types so we need
|
||||
// to explicitly cast it.
|
||||
uint32_t instr = static_cast<uint32_t>(instr_ptr[0]);
|
||||
instr = encoder->Encode(instr, from, this);
|
||||
// The Encode method should not ever set the top 16 bits.
|
||||
VIXL_ASSERT((instr & ~0xffff) == 0);
|
||||
instr_ptr[0] = static_cast<uint16_t>(instr);
|
||||
} else {
|
||||
uint32_t instr =
|
||||
instr_ptr[1] | (static_cast<uint32_t>(instr_ptr[0]) << 16);
|
||||
instr = encoder->Encode(instr, from, this);
|
||||
instr_ptr[0] = static_cast<uint16_t>(instr >> 16);
|
||||
instr_ptr[1] = static_cast<uint16_t>(instr);
|
||||
}
|
||||
} else {
|
||||
uint32_t* instr_ptr =
|
||||
assembler->GetBuffer()->GetOffsetAddress<uint32_t*>(from);
|
||||
instr_ptr[0] = encoder->Encode(instr_ptr[0], from, this);
|
||||
}
|
||||
}
|
||||
|
||||
void Location::AddForwardRef(int32_t instr_location,
|
||||
const EmitOperator& op,
|
||||
const ReferenceInfo* info) {
|
||||
VIXL_ASSERT(referenced_);
|
||||
int32_t from = instr_location + (op.IsUsingT32() ? kT32PcDelta : kA32PcDelta);
|
||||
if (info->pc_needs_aligning == ReferenceInfo::kAlignPc)
|
||||
from = AlignDown(from, 4);
|
||||
int32_t min_object_location = from + info->min_offset;
|
||||
int32_t max_object_location = from + info->max_offset;
|
||||
forward_.insert(ForwardRef(&op,
|
||||
instr_location,
|
||||
info->size,
|
||||
min_object_location,
|
||||
max_object_location,
|
||||
info->alignment));
|
||||
}
|
||||
|
||||
int Location::GetMaxAlignment() const {
|
||||
int max_alignment = GetPoolObjectAlignment();
|
||||
for (ForwardRefListIterator it(const_cast<Location*>(this)); !it.Done();
|
||||
it.Advance()) {
|
||||
const ForwardRef& reference = *it.Current();
|
||||
if (reference.GetAlignment() > max_alignment)
|
||||
max_alignment = reference.GetAlignment();
|
||||
}
|
||||
return max_alignment;
|
||||
}
|
||||
|
||||
int Location::GetMinLocation() const {
|
||||
int32_t min_location = 0;
|
||||
for (ForwardRefListIterator it(const_cast<Location*>(this)); !it.Done();
|
||||
it.Advance()) {
|
||||
const ForwardRef& reference = *it.Current();
|
||||
if (reference.GetMinLocation() > min_location)
|
||||
min_location = reference.GetMinLocation();
|
||||
}
|
||||
return min_location;
|
||||
}
|
||||
|
||||
void Label::UpdatePoolObject(PoolObject<int32_t>* object) {
|
||||
VIXL_ASSERT(forward_.size() == 1);
|
||||
const ForwardRef& reference = forward_.Front();
|
||||
object->Update(reference.GetMinLocation(),
|
||||
reference.GetMaxLocation(),
|
||||
reference.GetAlignment());
|
||||
}
|
||||
|
||||
void Label::EmitPoolObject(MacroAssemblerInterface* masm) {
|
||||
MacroAssembler* macro_assembler = static_cast<MacroAssembler*>(masm);
|
||||
|
||||
// Add a new branch to this label.
|
||||
macro_assembler->GetBuffer()->EnsureSpaceFor(kMaxInstructionSizeInBytes);
|
||||
ExactAssemblyScopeWithoutPoolsCheck guard(macro_assembler,
|
||||
kMaxInstructionSizeInBytes,
|
||||
ExactAssemblyScope::kMaximumSize);
|
||||
macro_assembler->b(this);
|
||||
}
|
||||
|
||||
void RawLiteral::EmitPoolObject(MacroAssemblerInterface* masm) {
|
||||
Assembler* assembler = static_cast<Assembler*>(masm->AsAssemblerBase());
|
||||
|
||||
assembler->GetBuffer()->EnsureSpaceFor(GetSize());
|
||||
assembler->GetBuffer()->EmitData(GetDataAddress(), GetSize());
|
||||
}
|
||||
}
|
||||
}
|
2312
dep/vixl/src/aarch32/macro-assembler-aarch32.cc
Normal file
2312
dep/vixl/src/aarch32/macro-assembler-aarch32.cc
Normal file
File diff suppressed because it is too large
Load Diff
563
dep/vixl/src/aarch32/operands-aarch32.cc
Normal file
563
dep/vixl/src/aarch32/operands-aarch32.cc
Normal file
@ -0,0 +1,563 @@
|
||||
// Copyright 2017, VIXL authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of ARM Limited nor the names of its contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
extern "C" {
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
}
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include "utils-vixl.h"
|
||||
#include "aarch32/constants-aarch32.h"
|
||||
#include "aarch32/instructions-aarch32.h"
|
||||
#include "aarch32/operands-aarch32.h"
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch32 {
|
||||
|
||||
// Operand
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Operand& operand) {
|
||||
if (operand.IsImmediate()) {
|
||||
return os << "#" << operand.GetImmediate();
|
||||
}
|
||||
if (operand.IsImmediateShiftedRegister()) {
|
||||
if ((operand.GetShift().IsLSL() || operand.GetShift().IsROR()) &&
|
||||
(operand.GetShiftAmount() == 0)) {
|
||||
return os << operand.GetBaseRegister();
|
||||
}
|
||||
if (operand.GetShift().IsRRX()) {
|
||||
return os << operand.GetBaseRegister() << ", rrx";
|
||||
}
|
||||
return os << operand.GetBaseRegister() << ", " << operand.GetShift() << " #"
|
||||
<< operand.GetShiftAmount();
|
||||
}
|
||||
if (operand.IsRegisterShiftedRegister()) {
|
||||
return os << operand.GetBaseRegister() << ", " << operand.GetShift() << " "
|
||||
<< operand.GetShiftRegister();
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const NeonImmediate& neon_imm) {
|
||||
if (neon_imm.IsDouble()) {
|
||||
if (neon_imm.imm_.d_ == 0) {
|
||||
if (copysign(1.0, neon_imm.imm_.d_) < 0.0) {
|
||||
return os << "#-0.0";
|
||||
}
|
||||
return os << "#0.0";
|
||||
}
|
||||
return os << "#" << std::setprecision(9) << neon_imm.imm_.d_;
|
||||
}
|
||||
if (neon_imm.IsFloat()) {
|
||||
if (neon_imm.imm_.f_ == 0) {
|
||||
if (copysign(1.0, neon_imm.imm_.d_) < 0.0) return os << "#-0.0";
|
||||
return os << "#0.0";
|
||||
}
|
||||
return os << "#" << std::setprecision(9) << neon_imm.imm_.f_;
|
||||
}
|
||||
if (neon_imm.IsInteger64()) {
|
||||
return os << "#0x" << std::hex << std::setw(16) << std::setfill('0')
|
||||
<< neon_imm.imm_.u64_ << std::dec;
|
||||
}
|
||||
return os << "#" << neon_imm.imm_.u32_;
|
||||
}
|
||||
|
||||
// SOperand
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const SOperand& operand) {
|
||||
if (operand.IsImmediate()) {
|
||||
return os << operand.GetNeonImmediate();
|
||||
}
|
||||
return os << operand.GetRegister();
|
||||
}
|
||||
|
||||
// DOperand
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const DOperand& operand) {
|
||||
if (operand.IsImmediate()) {
|
||||
return os << operand.GetNeonImmediate();
|
||||
}
|
||||
return os << operand.GetRegister();
|
||||
}
|
||||
|
||||
// QOperand
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const QOperand& operand) {
|
||||
if (operand.IsImmediate()) {
|
||||
return os << operand.GetNeonImmediate();
|
||||
}
|
||||
return os << operand.GetRegister();
|
||||
}
|
||||
|
||||
|
||||
ImmediateVbic::ImmediateVbic(DataType dt, const NeonImmediate& neon_imm) {
|
||||
if (neon_imm.IsInteger32()) {
|
||||
uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
|
||||
if (dt.GetValue() == I16) {
|
||||
if ((immediate & ~0xff) == 0) {
|
||||
SetEncodingValue(0x9);
|
||||
SetEncodedImmediate(immediate);
|
||||
} else if ((immediate & ~0xff00) == 0) {
|
||||
SetEncodingValue(0xb);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
}
|
||||
} else if (dt.GetValue() == I32) {
|
||||
if ((immediate & ~0xff) == 0) {
|
||||
SetEncodingValue(0x1);
|
||||
SetEncodedImmediate(immediate);
|
||||
} else if ((immediate & ~0xff00) == 0) {
|
||||
SetEncodingValue(0x3);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
} else if ((immediate & ~0xff0000) == 0) {
|
||||
SetEncodingValue(0x5);
|
||||
SetEncodedImmediate(immediate >> 16);
|
||||
} else if ((immediate & ~0xff000000) == 0) {
|
||||
SetEncodingValue(0x7);
|
||||
SetEncodedImmediate(immediate >> 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DataType ImmediateVbic::DecodeDt(uint32_t cmode) {
|
||||
switch (cmode) {
|
||||
case 0x1:
|
||||
case 0x3:
|
||||
case 0x5:
|
||||
case 0x7:
|
||||
return I32;
|
||||
case 0x9:
|
||||
case 0xb:
|
||||
return I16;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return kDataTypeValueInvalid;
|
||||
}
|
||||
|
||||
|
||||
NeonImmediate ImmediateVbic::DecodeImmediate(uint32_t cmode,
|
||||
uint32_t immediate) {
|
||||
switch (cmode) {
|
||||
case 0x1:
|
||||
case 0x9:
|
||||
return immediate;
|
||||
case 0x3:
|
||||
case 0xb:
|
||||
return immediate << 8;
|
||||
case 0x5:
|
||||
return immediate << 16;
|
||||
case 0x7:
|
||||
return immediate << 24;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ImmediateVmov::ImmediateVmov(DataType dt, const NeonImmediate& neon_imm) {
|
||||
if (neon_imm.IsInteger()) {
|
||||
switch (dt.GetValue()) {
|
||||
case I8:
|
||||
if (neon_imm.CanConvert<uint8_t>()) {
|
||||
SetEncodingValue(0xe);
|
||||
SetEncodedImmediate(neon_imm.GetImmediate<uint8_t>());
|
||||
}
|
||||
break;
|
||||
case I16:
|
||||
if (neon_imm.IsInteger32()) {
|
||||
uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
|
||||
if ((immediate & ~0xff) == 0) {
|
||||
SetEncodingValue(0x8);
|
||||
SetEncodedImmediate(immediate);
|
||||
} else if ((immediate & ~0xff00) == 0) {
|
||||
SetEncodingValue(0xa);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case I32:
|
||||
if (neon_imm.IsInteger32()) {
|
||||
uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
|
||||
if ((immediate & ~0xff) == 0) {
|
||||
SetEncodingValue(0x0);
|
||||
SetEncodedImmediate(immediate);
|
||||
} else if ((immediate & ~0xff00) == 0) {
|
||||
SetEncodingValue(0x2);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
} else if ((immediate & ~0xff0000) == 0) {
|
||||
SetEncodingValue(0x4);
|
||||
SetEncodedImmediate(immediate >> 16);
|
||||
} else if ((immediate & ~0xff000000) == 0) {
|
||||
SetEncodingValue(0x6);
|
||||
SetEncodedImmediate(immediate >> 24);
|
||||
} else if ((immediate & ~0xff00) == 0xff) {
|
||||
SetEncodingValue(0xc);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
} else if ((immediate & ~0xff0000) == 0xffff) {
|
||||
SetEncodingValue(0xd);
|
||||
SetEncodedImmediate(immediate >> 16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case I64: {
|
||||
bool is_valid = true;
|
||||
uint32_t encoding = 0;
|
||||
if (neon_imm.IsInteger32()) {
|
||||
uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
|
||||
uint32_t mask = 0xff000000;
|
||||
for (uint32_t set_bit = 1 << 3; set_bit != 0; set_bit >>= 1) {
|
||||
if ((immediate & mask) == mask) {
|
||||
encoding |= set_bit;
|
||||
} else if ((immediate & mask) != 0) {
|
||||
is_valid = false;
|
||||
break;
|
||||
}
|
||||
mask >>= 8;
|
||||
}
|
||||
} else {
|
||||
uint64_t immediate = neon_imm.GetImmediate<uint64_t>();
|
||||
uint64_t mask = UINT64_C(0xff) << 56;
|
||||
for (uint32_t set_bit = 1 << 7; set_bit != 0; set_bit >>= 1) {
|
||||
if ((immediate & mask) == mask) {
|
||||
encoding |= set_bit;
|
||||
} else if ((immediate & mask) != 0) {
|
||||
is_valid = false;
|
||||
break;
|
||||
}
|
||||
mask >>= 8;
|
||||
}
|
||||
}
|
||||
if (is_valid) {
|
||||
SetEncodingValue(0x1e);
|
||||
SetEncodedImmediate(encoding);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (dt.GetValue()) {
|
||||
case F32:
|
||||
if (neon_imm.IsFloat() || neon_imm.IsDouble()) {
|
||||
ImmediateVFP vfp(neon_imm.GetImmediate<float>());
|
||||
if (vfp.IsValid()) {
|
||||
SetEncodingValue(0xf);
|
||||
SetEncodedImmediate(vfp.GetEncodingValue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DataType ImmediateVmov::DecodeDt(uint32_t cmode) {
|
||||
switch (cmode & 0xf) {
|
||||
case 0x0:
|
||||
case 0x2:
|
||||
case 0x4:
|
||||
case 0x6:
|
||||
case 0xc:
|
||||
case 0xd:
|
||||
return I32;
|
||||
case 0x8:
|
||||
case 0xa:
|
||||
return I16;
|
||||
case 0xe:
|
||||
return ((cmode & 0x10) == 0) ? I8 : I64;
|
||||
case 0xf:
|
||||
if ((cmode & 0x10) == 0) return F32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return kDataTypeValueInvalid;
|
||||
}
|
||||
|
||||
|
||||
NeonImmediate ImmediateVmov::DecodeImmediate(uint32_t cmode,
|
||||
uint32_t immediate) {
|
||||
switch (cmode & 0xf) {
|
||||
case 0x8:
|
||||
case 0x0:
|
||||
return immediate;
|
||||
case 0x2:
|
||||
case 0xa:
|
||||
return immediate << 8;
|
||||
case 0x4:
|
||||
return immediate << 16;
|
||||
case 0x6:
|
||||
return immediate << 24;
|
||||
case 0xc:
|
||||
return (immediate << 8) | 0xff;
|
||||
case 0xd:
|
||||
return (immediate << 16) | 0xffff;
|
||||
case 0xe: {
|
||||
if (cmode == 0x1e) {
|
||||
uint64_t encoding = 0;
|
||||
for (uint32_t set_bit = 1 << 7; set_bit != 0; set_bit >>= 1) {
|
||||
encoding <<= 8;
|
||||
if ((immediate & set_bit) != 0) {
|
||||
encoding |= 0xff;
|
||||
}
|
||||
}
|
||||
return encoding;
|
||||
} else {
|
||||
return immediate;
|
||||
}
|
||||
}
|
||||
case 0xf: {
|
||||
return ImmediateVFP::Decode<float>(immediate);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ImmediateVmvn::ImmediateVmvn(DataType dt, const NeonImmediate& neon_imm) {
|
||||
if (neon_imm.IsInteger32()) {
|
||||
uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
|
||||
switch (dt.GetValue()) {
|
||||
case I16:
|
||||
if ((immediate & ~0xff) == 0) {
|
||||
SetEncodingValue(0x8);
|
||||
SetEncodedImmediate(immediate);
|
||||
} else if ((immediate & ~0xff00) == 0) {
|
||||
SetEncodingValue(0xa);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
}
|
||||
break;
|
||||
case I32:
|
||||
if ((immediate & ~0xff) == 0) {
|
||||
SetEncodingValue(0x0);
|
||||
SetEncodedImmediate(immediate);
|
||||
} else if ((immediate & ~0xff00) == 0) {
|
||||
SetEncodingValue(0x2);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
} else if ((immediate & ~0xff0000) == 0) {
|
||||
SetEncodingValue(0x4);
|
||||
SetEncodedImmediate(immediate >> 16);
|
||||
} else if ((immediate & ~0xff000000) == 0) {
|
||||
SetEncodingValue(0x6);
|
||||
SetEncodedImmediate(immediate >> 24);
|
||||
} else if ((immediate & ~0xff00) == 0xff) {
|
||||
SetEncodingValue(0xc);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
} else if ((immediate & ~0xff0000) == 0xffff) {
|
||||
SetEncodingValue(0xd);
|
||||
SetEncodedImmediate(immediate >> 16);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DataType ImmediateVmvn::DecodeDt(uint32_t cmode) {
|
||||
switch (cmode) {
|
||||
case 0x0:
|
||||
case 0x2:
|
||||
case 0x4:
|
||||
case 0x6:
|
||||
case 0xc:
|
||||
case 0xd:
|
||||
return I32;
|
||||
case 0x8:
|
||||
case 0xa:
|
||||
return I16;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return kDataTypeValueInvalid;
|
||||
}
|
||||
|
||||
|
||||
NeonImmediate ImmediateVmvn::DecodeImmediate(uint32_t cmode,
|
||||
uint32_t immediate) {
|
||||
switch (cmode) {
|
||||
case 0x0:
|
||||
case 0x8:
|
||||
return immediate;
|
||||
case 0x2:
|
||||
case 0xa:
|
||||
return immediate << 8;
|
||||
case 0x4:
|
||||
return immediate << 16;
|
||||
case 0x6:
|
||||
return immediate << 24;
|
||||
case 0xc:
|
||||
return (immediate << 8) | 0xff;
|
||||
case 0xd:
|
||||
return (immediate << 16) | 0xffff;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ImmediateVorr::ImmediateVorr(DataType dt, const NeonImmediate& neon_imm) {
|
||||
if (neon_imm.IsInteger32()) {
|
||||
uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
|
||||
if (dt.GetValue() == I16) {
|
||||
if ((immediate & ~0xff) == 0) {
|
||||
SetEncodingValue(0x9);
|
||||
SetEncodedImmediate(immediate);
|
||||
} else if ((immediate & ~0xff00) == 0) {
|
||||
SetEncodingValue(0xb);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
}
|
||||
} else if (dt.GetValue() == I32) {
|
||||
if ((immediate & ~0xff) == 0) {
|
||||
SetEncodingValue(0x1);
|
||||
SetEncodedImmediate(immediate);
|
||||
} else if ((immediate & ~0xff00) == 0) {
|
||||
SetEncodingValue(0x3);
|
||||
SetEncodedImmediate(immediate >> 8);
|
||||
} else if ((immediate & ~0xff0000) == 0) {
|
||||
SetEncodingValue(0x5);
|
||||
SetEncodedImmediate(immediate >> 16);
|
||||
} else if ((immediate & ~0xff000000) == 0) {
|
||||
SetEncodingValue(0x7);
|
||||
SetEncodedImmediate(immediate >> 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DataType ImmediateVorr::DecodeDt(uint32_t cmode) {
|
||||
switch (cmode) {
|
||||
case 0x1:
|
||||
case 0x3:
|
||||
case 0x5:
|
||||
case 0x7:
|
||||
return I32;
|
||||
case 0x9:
|
||||
case 0xb:
|
||||
return I16;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return kDataTypeValueInvalid;
|
||||
}
|
||||
|
||||
|
||||
NeonImmediate ImmediateVorr::DecodeImmediate(uint32_t cmode,
|
||||
uint32_t immediate) {
|
||||
switch (cmode) {
|
||||
case 0x1:
|
||||
case 0x9:
|
||||
return immediate;
|
||||
case 0x3:
|
||||
case 0xb:
|
||||
return immediate << 8;
|
||||
case 0x5:
|
||||
return immediate << 16;
|
||||
case 0x7:
|
||||
return immediate << 24;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// MemOperand
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const MemOperand& operand) {
|
||||
os << "[" << operand.GetBaseRegister();
|
||||
if (operand.GetAddrMode() == PostIndex) {
|
||||
os << "]";
|
||||
if (operand.IsRegisterOnly()) return os << "!";
|
||||
}
|
||||
if (operand.IsImmediate()) {
|
||||
if ((operand.GetOffsetImmediate() != 0) || operand.GetSign().IsMinus() ||
|
||||
((operand.GetAddrMode() != Offset) && !operand.IsRegisterOnly())) {
|
||||
if (operand.GetOffsetImmediate() == 0) {
|
||||
os << ", #" << operand.GetSign() << operand.GetOffsetImmediate();
|
||||
} else {
|
||||
os << ", #" << operand.GetOffsetImmediate();
|
||||
}
|
||||
}
|
||||
} else if (operand.IsPlainRegister()) {
|
||||
os << ", " << operand.GetSign() << operand.GetOffsetRegister();
|
||||
} else if (operand.IsShiftedRegister()) {
|
||||
os << ", " << operand.GetSign() << operand.GetOffsetRegister()
|
||||
<< ImmediateShiftOperand(operand.GetShift(), operand.GetShiftAmount());
|
||||
} else {
|
||||
VIXL_UNREACHABLE();
|
||||
return os;
|
||||
}
|
||||
if (operand.GetAddrMode() == Offset) {
|
||||
os << "]";
|
||||
} else if (operand.GetAddrMode() == PreIndex) {
|
||||
os << "]!";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const AlignedMemOperand& operand) {
|
||||
os << "[" << operand.GetBaseRegister() << operand.GetAlignment() << "]";
|
||||
if (operand.GetAddrMode() == PostIndex) {
|
||||
if (operand.IsPlainRegister()) {
|
||||
os << ", " << operand.GetOffsetRegister();
|
||||
} else {
|
||||
os << "!";
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace aarch32
|
||||
} // namespace vixl
|
Reference in New Issue
Block a user