mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-02 21:31:41 +00:00
[Hexagon] Enabling ASM parsing on Hexagon backend and adding instruction parsing tests. General updating of the code emission.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252443 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dd77c4496e
commit
c0aef701cc
7
lib/Target/Hexagon/AsmParser/CMakeLists.txt
Normal file
7
lib/Target/Hexagon/AsmParser/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
|
||||
|
||||
add_llvm_library(LLVMHexagonAsmParser
|
||||
HexagonAsmParser.cpp
|
||||
)
|
||||
|
||||
add_dependencies( LLVMHexagonAsmParser HexagonCommonTableGen )
|
2152
lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
Normal file
2152
lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
23
lib/Target/Hexagon/AsmParser/LLVMBuild.txt
Normal file
23
lib/Target/Hexagon/AsmParser/LLVMBuild.txt
Normal file
@ -0,0 +1,23 @@
|
||||
;===- ./lib/Target/Hexagon/AsmParser/LLVMBuild.txt --------------*- Conf -*-===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = HexagonAsmParser
|
||||
parent = Hexagon
|
||||
required_libraries = MC MCParser Support HexagonDesc HexagonInfo
|
||||
add_to_library_groups = Hexagon
|
15
lib/Target/Hexagon/AsmParser/Makefile
Normal file
15
lib/Target/Hexagon/AsmParser/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
##===- lib/Target/Hexagon/AsmParser/Makefile ------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
LEVEL = ../../../..
|
||||
LIBRARYNAME = LLVMHexagonAsmParser
|
||||
|
||||
# Hack: we need to include 'main' Hexagon target directory to grab private headers
|
||||
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
@ -1,5 +1,6 @@
|
||||
set(LLVM_TARGET_DEFINITIONS Hexagon.td)
|
||||
|
||||
tablegen(LLVM HexagonGenAsmMatcher.inc -gen-asm-matcher)
|
||||
tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer)
|
||||
tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
|
||||
@ -50,6 +51,7 @@ add_llvm_target(HexagonCodeGen
|
||||
HexagonVLIWPacketizer.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(AsmParser)
|
||||
add_subdirectory(TargetInfo)
|
||||
add_subdirectory(MCTargetDesc)
|
||||
add_subdirectory(Disassembler)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,5 +19,5 @@
|
||||
type = Library
|
||||
name = HexagonDisassembler
|
||||
parent = Hexagon
|
||||
required_libraries = HexagonDesc HexagonInfo MCDisassembler Support
|
||||
required_libraries = HexagonDesc HexagonInfo MC MCDisassembler Support
|
||||
add_to_library_groups = Hexagon
|
||||
|
@ -30,6 +30,9 @@ def ArchV60: SubtargetFeature<"v60", "HexagonArchVersion", "V60", "Hexagon V60">
|
||||
// Hexagon ISA Extensions
|
||||
def ExtensionHVX: SubtargetFeature<"hvx", "UseHVXOps",
|
||||
"true", "Hexagon HVX instructions">;
|
||||
def ExtensionHVXDbl: SubtargetFeature<"hvxDbl", "UseHVXDblOps",
|
||||
"true", "Hexagon HVX Double instructions">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Hexagon Instruction Predicate Definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -212,7 +215,13 @@ def : Proc<"hexagonv5", HexagonModelV4,
|
||||
// Declare the target which we are implementing
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def HexagonAsmParserVariant : AsmParserVariant {
|
||||
int Variant = 0;
|
||||
string TokenizingCharacters = "#()=:.<>!+*";
|
||||
}
|
||||
|
||||
def Hexagon : Target {
|
||||
// Pull in Instruction Info:
|
||||
let InstructionSet = HexagonInstrInfo;
|
||||
let AssemblyParserVariants = [HexagonAsmParserVariant];
|
||||
}
|
||||
|
@ -73,11 +73,14 @@ void llvm::HexagonLowerToMC(MachineInstr const* MI, MCInst& MCB,
|
||||
APFloat Val = MO.getFPImm()->getValueAPF();
|
||||
// FP immediates are used only when setting GPRs, so they may be dealt
|
||||
// with like regular immediates from this point on.
|
||||
MCO = MCOperand::createImm(*Val.bitcastToAPInt().getRawData());
|
||||
MCO = MCOperand::createExpr(
|
||||
MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(),
|
||||
AP.OutContext));
|
||||
break;
|
||||
}
|
||||
case MachineOperand::MO_Immediate:
|
||||
MCO = MCOperand::createImm(MO.getImm());
|
||||
MCO = MCOperand::createExpr(
|
||||
MCConstantExpr::create(MO.getImm(), AP.OutContext));
|
||||
break;
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
MCO = MCOperand::createExpr
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===- HexagonOperands.td - Hexagon immediate processing -*- tablegen -*-===//
|
||||
//===- HexagonImmediates.td - Hexagon immediate processing -*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,57 +7,100 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def s32ImmOperand : AsmOperandClass { let Name = "s32Imm"; }
|
||||
def s8ImmOperand : AsmOperandClass { let Name = "s8Imm"; }
|
||||
def s8Imm64Operand : AsmOperandClass { let Name = "s8Imm64"; }
|
||||
def s6ImmOperand : AsmOperandClass { let Name = "s6Imm"; }
|
||||
def s4ImmOperand : AsmOperandClass { let Name = "s4Imm"; }
|
||||
def s4_0ImmOperand : AsmOperandClass { let Name = "s4_0Imm"; }
|
||||
def s4_1ImmOperand : AsmOperandClass { let Name = "s4_1Imm"; }
|
||||
def s4_2ImmOperand : AsmOperandClass { let Name = "s4_2Imm"; }
|
||||
def s4_3ImmOperand : AsmOperandClass { let Name = "s4_3Imm"; }
|
||||
def s4_6ImmOperand : AsmOperandClass { let Name = "s4_6Imm"; }
|
||||
def s3_6ImmOperand : AsmOperandClass { let Name = "s3_6Imm"; }
|
||||
|
||||
def u64ImmOperand : AsmOperandClass { let Name = "u64Imm"; }
|
||||
def u32ImmOperand : AsmOperandClass { let Name = "u32Imm"; }
|
||||
def u26_6ImmOperand : AsmOperandClass { let Name = "u26_6Imm"; }
|
||||
def u16ImmOperand : AsmOperandClass { let Name = "u16Imm"; }
|
||||
def u16_0ImmOperand : AsmOperandClass { let Name = "u16_0Imm"; }
|
||||
def u16_1ImmOperand : AsmOperandClass { let Name = "u16_1Imm"; }
|
||||
def u16_2ImmOperand : AsmOperandClass { let Name = "u16_2Imm"; }
|
||||
def u16_3ImmOperand : AsmOperandClass { let Name = "u16_3Imm"; }
|
||||
def u11_3ImmOperand : AsmOperandClass { let Name = "u11_3Imm"; }
|
||||
def u10ImmOperand : AsmOperandClass { let Name = "u10Imm"; }
|
||||
def u9ImmOperand : AsmOperandClass { let Name = "u9Imm"; }
|
||||
def u8ImmOperand : AsmOperandClass { let Name = "u8Imm"; }
|
||||
def u7ImmOperand : AsmOperandClass { let Name = "u7Imm"; }
|
||||
def u6ImmOperand : AsmOperandClass { let Name = "u6Imm"; }
|
||||
def u6_0ImmOperand : AsmOperandClass { let Name = "u6_0Imm"; }
|
||||
def u6_1ImmOperand : AsmOperandClass { let Name = "u6_1Imm"; }
|
||||
def u6_2ImmOperand : AsmOperandClass { let Name = "u6_2Imm"; }
|
||||
def u6_3ImmOperand : AsmOperandClass { let Name = "u6_3Imm"; }
|
||||
def u5ImmOperand : AsmOperandClass { let Name = "u5Imm"; }
|
||||
def u4ImmOperand : AsmOperandClass { let Name = "u4Imm"; }
|
||||
def u3ImmOperand : AsmOperandClass { let Name = "u3Imm"; }
|
||||
def u2ImmOperand : AsmOperandClass { let Name = "u2Imm"; }
|
||||
def u1ImmOperand : AsmOperandClass { let Name = "u1Imm"; }
|
||||
def n8ImmOperand : AsmOperandClass { let Name = "n8Imm"; }
|
||||
// Immediate operands.
|
||||
|
||||
let PrintMethod = "printImmOperand" in {
|
||||
def s32Imm : Operand<i32>;
|
||||
def s8Imm : Operand<i32>;
|
||||
def s8Imm64 : Operand<i64>;
|
||||
def s6Imm : Operand<i32>;
|
||||
let OperandType = "OPERAND_IMMEDIATE",
|
||||
DecoderMethod = "unsignedImmDecoder" in {
|
||||
def s32Imm : Operand<i32> { let ParserMatchClass = s32ImmOperand;
|
||||
let DecoderMethod = "s32ImmDecoder"; }
|
||||
def s8Imm : Operand<i32> { let ParserMatchClass = s8ImmOperand;
|
||||
let DecoderMethod = "s8ImmDecoder"; }
|
||||
def s8Imm64 : Operand<i64> { let ParserMatchClass = s8Imm64Operand;
|
||||
let DecoderMethod = "s8ImmDecoder"; }
|
||||
def s6Imm : Operand<i32> { let ParserMatchClass = s6ImmOperand;
|
||||
let DecoderMethod = "s6_0ImmDecoder"; }
|
||||
def s6_3Imm : Operand<i32>;
|
||||
def s4Imm : Operand<i32>;
|
||||
def s4_0Imm : Operand<i32> { let DecoderMethod = "s4_0ImmDecoder"; }
|
||||
def s4_1Imm : Operand<i32> { let DecoderMethod = "s4_1ImmDecoder"; }
|
||||
def s4_2Imm : Operand<i32> { let DecoderMethod = "s4_2ImmDecoder"; }
|
||||
def s4_3Imm : Operand<i32> { let DecoderMethod = "s4_3ImmDecoder"; }
|
||||
def u64Imm : Operand<i64>;
|
||||
def u32Imm : Operand<i32>;
|
||||
def u26_6Imm : Operand<i32>;
|
||||
def u16Imm : Operand<i32>;
|
||||
def u16_0Imm : Operand<i32>;
|
||||
def u16_1Imm : Operand<i32>;
|
||||
def u16_2Imm : Operand<i32>;
|
||||
def u16_3Imm : Operand<i32>;
|
||||
def u11_3Imm : Operand<i32>;
|
||||
def u10Imm : Operand<i32>;
|
||||
def u9Imm : Operand<i32>;
|
||||
def u8Imm : Operand<i32>;
|
||||
def u7Imm : Operand<i32>;
|
||||
def u6Imm : Operand<i32>;
|
||||
def u6_0Imm : Operand<i32>;
|
||||
def u6_1Imm : Operand<i32>;
|
||||
def u6_2Imm : Operand<i32>;
|
||||
def u6_3Imm : Operand<i32>;
|
||||
def u5Imm : Operand<i32>;
|
||||
def s4Imm : Operand<i32> { let ParserMatchClass = s4ImmOperand;
|
||||
let DecoderMethod = "s4_0ImmDecoder"; }
|
||||
def s4_0Imm : Operand<i32> { let ParserMatchClass = s4_0ImmOperand;
|
||||
let DecoderMethod = "s4_0ImmDecoder"; }
|
||||
def s4_1Imm : Operand<i32> { let ParserMatchClass = s4_1ImmOperand;
|
||||
let DecoderMethod = "s4_1ImmDecoder"; }
|
||||
def s4_2Imm : Operand<i32> { let ParserMatchClass = s4_2ImmOperand;
|
||||
let DecoderMethod = "s4_2ImmDecoder"; }
|
||||
def s4_3Imm : Operand<i32> { let ParserMatchClass = s4_3ImmOperand;
|
||||
let DecoderMethod = "s4_3ImmDecoder"; }
|
||||
def u64Imm : Operand<i64> { let ParserMatchClass = u64ImmOperand; }
|
||||
def u32Imm : Operand<i32> { let ParserMatchClass = u32ImmOperand; }
|
||||
def u26_6Imm : Operand<i32> { let ParserMatchClass = u26_6ImmOperand; }
|
||||
def u16Imm : Operand<i32> { let ParserMatchClass = u16ImmOperand; }
|
||||
def u16_0Imm : Operand<i32> { let ParserMatchClass = u16_0ImmOperand; }
|
||||
def u16_1Imm : Operand<i32> { let ParserMatchClass = u16_1ImmOperand; }
|
||||
def u16_2Imm : Operand<i32> { let ParserMatchClass = u16_2ImmOperand; }
|
||||
def u16_3Imm : Operand<i32> { let ParserMatchClass = u16_3ImmOperand; }
|
||||
def u11_3Imm : Operand<i32> { let ParserMatchClass = u11_3ImmOperand; }
|
||||
def u10Imm : Operand<i32> { let ParserMatchClass = u10ImmOperand; }
|
||||
def u9Imm : Operand<i32> { let ParserMatchClass = u9ImmOperand; }
|
||||
def u8Imm : Operand<i32> { let ParserMatchClass = u8ImmOperand; }
|
||||
def u7Imm : Operand<i32> { let ParserMatchClass = u7ImmOperand; }
|
||||
def u6Imm : Operand<i32> { let ParserMatchClass = u6ImmOperand; }
|
||||
def u6_0Imm : Operand<i32> { let ParserMatchClass = u6_0ImmOperand; }
|
||||
def u6_1Imm : Operand<i32> { let ParserMatchClass = u6_1ImmOperand; }
|
||||
def u6_2Imm : Operand<i32> { let ParserMatchClass = u6_2ImmOperand; }
|
||||
def u6_3Imm : Operand<i32> { let ParserMatchClass = u6_3ImmOperand; }
|
||||
def u5Imm : Operand<i32> { let ParserMatchClass = u5ImmOperand; }
|
||||
def u5_0Imm : Operand<i32>;
|
||||
def u5_1Imm : Operand<i32>;
|
||||
def u5_2Imm : Operand<i32>;
|
||||
def u5_3Imm : Operand<i32>;
|
||||
def u4Imm : Operand<i32>;
|
||||
def u4Imm : Operand<i32> { let ParserMatchClass = u4ImmOperand; }
|
||||
def u4_0Imm : Operand<i32>;
|
||||
def u4_1Imm : Operand<i32>;
|
||||
def u4_2Imm : Operand<i32>;
|
||||
def u3Imm : Operand<i32>;
|
||||
def u4_3Imm : Operand<i32>;
|
||||
def u3Imm : Operand<i32> { let ParserMatchClass = u3ImmOperand; }
|
||||
def u3_0Imm : Operand<i32>;
|
||||
def u3_1Imm : Operand<i32>;
|
||||
def u2Imm : Operand<i32>;
|
||||
def u1Imm : Operand<i32>;
|
||||
def n8Imm : Operand<i32>;
|
||||
def m6Imm : Operand<i32>;
|
||||
def u3_2Imm : Operand<i32>;
|
||||
def u3_3Imm : Operand<i32>;
|
||||
def u2Imm : Operand<i32> { let ParserMatchClass = u2ImmOperand; }
|
||||
def u1Imm : Operand<i32> { let ParserMatchClass = u1ImmOperand; }
|
||||
def n8Imm : Operand<i32> { let ParserMatchClass = n8ImmOperand; }
|
||||
}
|
||||
|
||||
let OperandType = "OPERAND_IMMEDIATE" in {
|
||||
@ -73,9 +116,6 @@ let OperandType = "OPERAND_IMMEDIATE" in {
|
||||
let DecoderMethod = "s3_6ImmDecoder";}
|
||||
}
|
||||
|
||||
let PrintMethod = "printNOneImmOperand" in
|
||||
def nOneImm : Operand<i32>;
|
||||
|
||||
//
|
||||
// Immediate predicates
|
||||
//
|
||||
@ -169,7 +209,6 @@ def s4_3ImmPred : PatLeaf<(i32 imm), [{
|
||||
return isShiftedInt<4,3>(v);
|
||||
}]>;
|
||||
|
||||
|
||||
def u64ImmPred : PatLeaf<(i64 imm), [{
|
||||
// Adding "N ||" to suppress gcc unused warning.
|
||||
return (N || true);
|
||||
@ -225,6 +264,11 @@ def u11_3ImmPred : PatLeaf<(i32 imm), [{
|
||||
return isShiftedUInt<11,3>(v);
|
||||
}]>;
|
||||
|
||||
def u10ImmPred : PatLeaf<(i32 imm), [{
|
||||
int64_t v = (int64_t)N->getSExtValue();
|
||||
return isUInt<10>(v);
|
||||
}]>;
|
||||
|
||||
def u9ImmPred : PatLeaf<(i32 imm), [{
|
||||
int64_t v = (int64_t)N->getSExtValue();
|
||||
return isUInt<9>(v);
|
||||
@ -296,6 +340,11 @@ def u1ImmPred : PatLeaf<(i1 imm), [{
|
||||
return isUInt<1>(v);
|
||||
}]>;
|
||||
|
||||
def u1ImmPred32 : PatLeaf<(i32 imm), [{
|
||||
int64_t v = (int64_t)N->getSExtValue();
|
||||
return isUInt<1>(v);
|
||||
}]>;
|
||||
|
||||
def m5BImmPred : PatLeaf<(i32 imm), [{
|
||||
// m5BImmPred predicate - True if the (char) number is in range -1 .. -31
|
||||
// and will fit in a 5 bit field when made positive, for use in memops.
|
||||
@ -408,29 +457,65 @@ def SetClr3ImmPred : PatLeaf<(i32 imm), [{
|
||||
|
||||
|
||||
// Extendable immediate operands.
|
||||
def f32ExtOperand : AsmOperandClass { let Name = "f32Ext"; }
|
||||
def s16ExtOperand : AsmOperandClass { let Name = "s16Ext"; }
|
||||
def s12ExtOperand : AsmOperandClass { let Name = "s12Ext"; }
|
||||
def s10ExtOperand : AsmOperandClass { let Name = "s10Ext"; }
|
||||
def s9ExtOperand : AsmOperandClass { let Name = "s9Ext"; }
|
||||
def s8ExtOperand : AsmOperandClass { let Name = "s8Ext"; }
|
||||
def s7ExtOperand : AsmOperandClass { let Name = "s7Ext"; }
|
||||
def s6ExtOperand : AsmOperandClass { let Name = "s6Ext"; }
|
||||
def s11_0ExtOperand : AsmOperandClass { let Name = "s11_0Ext"; }
|
||||
def s11_1ExtOperand : AsmOperandClass { let Name = "s11_1Ext"; }
|
||||
def s11_2ExtOperand : AsmOperandClass { let Name = "s11_2Ext"; }
|
||||
def s11_3ExtOperand : AsmOperandClass { let Name = "s11_3Ext"; }
|
||||
def u6ExtOperand : AsmOperandClass { let Name = "u6Ext"; }
|
||||
def u7ExtOperand : AsmOperandClass { let Name = "u7Ext"; }
|
||||
def u8ExtOperand : AsmOperandClass { let Name = "u8Ext"; }
|
||||
def u9ExtOperand : AsmOperandClass { let Name = "u9Ext"; }
|
||||
def u10ExtOperand : AsmOperandClass { let Name = "u10Ext"; }
|
||||
def u6_0ExtOperand : AsmOperandClass { let Name = "u6_0Ext"; }
|
||||
def u6_1ExtOperand : AsmOperandClass { let Name = "u6_1Ext"; }
|
||||
def u6_2ExtOperand : AsmOperandClass { let Name = "u6_2Ext"; }
|
||||
def u6_3ExtOperand : AsmOperandClass { let Name = "u6_3Ext"; }
|
||||
def u32MustExtOperand : AsmOperandClass { let Name = "u32MustExt"; }
|
||||
|
||||
let PrintMethod = "printExtOperand" in {
|
||||
def f32Ext : Operand<f32>;
|
||||
def s16Ext : Operand<i32> { let DecoderMethod = "s16ImmDecoder"; }
|
||||
def s12Ext : Operand<i32> { let DecoderMethod = "s12ImmDecoder"; }
|
||||
def s11_0Ext : Operand<i32> { let DecoderMethod = "s11_0ImmDecoder"; }
|
||||
def s11_1Ext : Operand<i32> { let DecoderMethod = "s11_1ImmDecoder"; }
|
||||
def s11_2Ext : Operand<i32> { let DecoderMethod = "s11_2ImmDecoder"; }
|
||||
def s11_3Ext : Operand<i32> { let DecoderMethod = "s11_3ImmDecoder"; }
|
||||
def s10Ext : Operand<i32> { let DecoderMethod = "s10ImmDecoder"; }
|
||||
def s9Ext : Operand<i32> { let DecoderMethod = "s90ImmDecoder"; }
|
||||
def s8Ext : Operand<i32> { let DecoderMethod = "s8ImmDecoder"; }
|
||||
def s7Ext : Operand<i32>;
|
||||
def s6Ext : Operand<i32> { let DecoderMethod = "s6_0ImmDecoder"; }
|
||||
def u6Ext : Operand<i32>;
|
||||
def u7Ext : Operand<i32>;
|
||||
def u8Ext : Operand<i32>;
|
||||
def u9Ext : Operand<i32>;
|
||||
def u10Ext : Operand<i32>;
|
||||
def u6_0Ext : Operand<i32>;
|
||||
def u6_1Ext : Operand<i32>;
|
||||
def u6_2Ext : Operand<i32>;
|
||||
def u6_3Ext : Operand<i32>;
|
||||
|
||||
|
||||
let OperandType = "OPERAND_IMMEDIATE", PrintMethod = "printExtOperand",
|
||||
DecoderMethod = "unsignedImmDecoder" in {
|
||||
def f32Ext : Operand<f32> { let ParserMatchClass = f32ExtOperand; }
|
||||
def s16Ext : Operand<i32> { let ParserMatchClass = s16ExtOperand;
|
||||
let DecoderMethod = "s16ImmDecoder"; }
|
||||
def s12Ext : Operand<i32> { let ParserMatchClass = s12ExtOperand;
|
||||
let DecoderMethod = "s12ImmDecoder"; }
|
||||
def s11_0Ext : Operand<i32> { let ParserMatchClass = s11_0ExtOperand;
|
||||
let DecoderMethod = "s11_0ImmDecoder"; }
|
||||
def s11_1Ext : Operand<i32> { let ParserMatchClass = s11_1ExtOperand;
|
||||
let DecoderMethod = "s11_1ImmDecoder"; }
|
||||
def s11_2Ext : Operand<i32> { let ParserMatchClass = s11_2ExtOperand;
|
||||
let DecoderMethod = "s11_2ImmDecoder"; }
|
||||
def s11_3Ext : Operand<i32> { let ParserMatchClass = s11_3ExtOperand;
|
||||
let DecoderMethod = "s11_3ImmDecoder"; }
|
||||
def s10Ext : Operand<i32> { let ParserMatchClass = s10ExtOperand;
|
||||
let DecoderMethod = "s10ImmDecoder"; }
|
||||
def s9Ext : Operand<i32> { let ParserMatchClass = s9ExtOperand;
|
||||
let DecoderMethod = "s90ImmDecoder"; }
|
||||
def s8Ext : Operand<i32> { let ParserMatchClass = s8ExtOperand;
|
||||
let DecoderMethod = "s8ImmDecoder"; }
|
||||
def s7Ext : Operand<i32> { let ParserMatchClass = s7ExtOperand; }
|
||||
def s6Ext : Operand<i32> { let ParserMatchClass = s6ExtOperand;
|
||||
let DecoderMethod = "s6_0ImmDecoder"; }
|
||||
def u6Ext : Operand<i32> { let ParserMatchClass = u6ExtOperand; }
|
||||
def u7Ext : Operand<i32> { let ParserMatchClass = u7ExtOperand; }
|
||||
def u8Ext : Operand<i32> { let ParserMatchClass = u8ExtOperand; }
|
||||
def u9Ext : Operand<i32> { let ParserMatchClass = u9ExtOperand; }
|
||||
def u10Ext : Operand<i32> { let ParserMatchClass = u10ExtOperand; }
|
||||
def u6_0Ext : Operand<i32> { let ParserMatchClass = u6_0ExtOperand; }
|
||||
def u6_1Ext : Operand<i32> { let ParserMatchClass = u6_1ExtOperand; }
|
||||
def u6_2Ext : Operand<i32> { let ParserMatchClass = u6_2ExtOperand; }
|
||||
def u6_3Ext : Operand<i32> { let ParserMatchClass = u6_3ExtOperand; }
|
||||
def u32MustExt : Operand<i32> { let ParserMatchClass = u32MustExtOperand; }
|
||||
}
|
||||
|
||||
|
||||
@ -492,21 +577,21 @@ let PrintMethod = "printGlobalOperand" in {
|
||||
let PrintMethod = "printJumpTable" in
|
||||
def jumptablebase : Operand<i32>;
|
||||
|
||||
def brtarget : Operand<OtherVT>;
|
||||
def brtargetExt : Operand<OtherVT> {
|
||||
let PrintMethod = "printExtBrtarget";
|
||||
def brtarget : Operand<OtherVT> {
|
||||
let DecoderMethod = "brtargetDecoder";
|
||||
let PrintMethod = "printBrtarget";
|
||||
}
|
||||
def brtargetExt : Operand<OtherVT> {
|
||||
let DecoderMethod = "brtargetDecoder";
|
||||
let PrintMethod = "printBrtarget";
|
||||
}
|
||||
def calltarget : Operand<i32> {
|
||||
let DecoderMethod = "brtargetDecoder";
|
||||
let PrintMethod = "printBrtarget";
|
||||
}
|
||||
def calltarget : Operand<i32>;
|
||||
|
||||
def bblabel : Operand<i32>;
|
||||
def bbl : SDNode<"ISD::BasicBlock", SDTPtrLeaf , [], "BasicBlockSDNode">;
|
||||
|
||||
def symbolHi32 : Operand<i32> {
|
||||
let PrintMethod = "printSymbolHi";
|
||||
}
|
||||
def symbolLo32 : Operand<i32> {
|
||||
let PrintMethod = "printSymbolLo";
|
||||
}
|
||||
def bbl : SDNode<"ISD::BasicBlock", SDTPtrLeaf, [], "BasicBlockSDNode">;
|
||||
|
||||
// Return true if for a 32 to 64-bit sign-extended load.
|
||||
def is_sext_i32 : PatLeaf<(i64 DoubleRegs:$src1), [{
|
||||
|
@ -137,20 +137,21 @@ let Namespace = "Hexagon" in {
|
||||
def LC1 : Rc<3, "lc1", ["c3"]>, DwarfRegNum<[70]>;
|
||||
def P3_0 : Rc<4, "p3:0", ["c4"], [P0, P1, P2, P3]>,
|
||||
DwarfRegNum<[71]>;
|
||||
def C6 : Rc<6, "c6", [], [M0]>, DwarfRegNum<[72]>;
|
||||
def C7 : Rc<7, "c7", [], [M1]>, DwarfRegNum<[73]>;
|
||||
def C5 : Rc<5, "c5", ["c5"]>, DwarfRegNum<[72]>; // future use
|
||||
def C6 : Rc<6, "c6", [], [M0]>, DwarfRegNum<[73]>;
|
||||
def C7 : Rc<7, "c7", [], [M1]>, DwarfRegNum<[74]>;
|
||||
|
||||
def USR : Rc<8, "usr", ["c8"]>, DwarfRegNum<[74]> {
|
||||
def USR : Rc<8, "usr", ["c8"]>, DwarfRegNum<[75]> {
|
||||
let SubRegIndices = [subreg_overflow];
|
||||
let SubRegs = [USR_OVF];
|
||||
}
|
||||
def PC : Rc<9, "pc">, DwarfRegNum<[75]>;
|
||||
def UGP : Rc<10, "ugp", ["c10"]>, DwarfRegNum<[76]>;
|
||||
def GP : Rc<11, "gp">, DwarfRegNum<[77]>;
|
||||
def CS0 : Rc<12, "cs0", ["c12"]>, DwarfRegNum<[78]>;
|
||||
def CS1 : Rc<13, "cs1", ["c13"]>, DwarfRegNum<[79]>;
|
||||
def UPCL : Rc<14, "upcyclelo", ["c14"]>, DwarfRegNum<[80]>;
|
||||
def UPCH : Rc<15, "upcyclehi", ["c15"]>, DwarfRegNum<[81]>;
|
||||
def PC : Rc<9, "pc">, DwarfRegNum<[76]>;
|
||||
def UGP : Rc<10, "ugp", ["c10"]>, DwarfRegNum<[77]>;
|
||||
def GP : Rc<11, "gp">, DwarfRegNum<[78]>;
|
||||
def CS0 : Rc<12, "cs0", ["c12"]>, DwarfRegNum<[79]>;
|
||||
def CS1 : Rc<13, "cs1", ["c13"]>, DwarfRegNum<[80]>;
|
||||
def UPCL : Rc<14, "upcyclelo", ["c14"]>, DwarfRegNum<[81]>;
|
||||
def UPCH : Rc<15, "upcyclehi", ["c15"]>, DwarfRegNum<[82]>;
|
||||
}
|
||||
|
||||
// Control registers pairs.
|
||||
|
@ -16,7 +16,7 @@
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[common]
|
||||
subdirectories = Disassembler MCTargetDesc TargetInfo
|
||||
subdirectories = AsmParser Disassembler MCTargetDesc TargetInfo
|
||||
|
||||
[component_0]
|
||||
type = TargetGroup
|
||||
|
@ -3,10 +3,12 @@ add_llvm_library(LLVMHexagonDesc
|
||||
HexagonELFObjectWriter.cpp
|
||||
HexagonInstPrinter.cpp
|
||||
HexagonMCAsmInfo.cpp
|
||||
HexagonMCChecker.cpp
|
||||
HexagonMCCodeEmitter.cpp
|
||||
HexagonMCCompound.cpp
|
||||
HexagonMCDuplexInfo.cpp
|
||||
HexagonMCELFStreamer.cpp
|
||||
HexagonMCExpr.cpp
|
||||
HexagonMCInstrInfo.cpp
|
||||
HexagonMCShuffler.cpp
|
||||
HexagonMCTargetDesc.cpp
|
||||
|
@ -44,6 +44,25 @@ namespace HexagonII {
|
||||
TypeMEMOP = 9,
|
||||
TypeNV = 10,
|
||||
TypeDUPLEX = 11,
|
||||
TypeCOMPOUND = 12,
|
||||
TypeCVI_FIRST = 13,
|
||||
TypeCVI_VA = TypeCVI_FIRST,
|
||||
TypeCVI_VA_DV = 14,
|
||||
TypeCVI_VX = 15,
|
||||
TypeCVI_VX_DV = 16,
|
||||
TypeCVI_VP = 17,
|
||||
TypeCVI_VP_VS = 18,
|
||||
TypeCVI_VS = 19,
|
||||
TypeCVI_VINLANESAT= 20,
|
||||
TypeCVI_VM_LD = 21,
|
||||
TypeCVI_VM_TMP_LD = 22,
|
||||
TypeCVI_VM_CUR_LD = 23,
|
||||
TypeCVI_VM_VP_LDU = 24,
|
||||
TypeCVI_VM_ST = 25,
|
||||
TypeCVI_VM_NEW_ST = 26,
|
||||
TypeCVI_VM_STU = 27,
|
||||
TypeCVI_HIST = 28,
|
||||
TypeCVI_LAST = TypeCVI_HIST,
|
||||
TypePREFIX = 30, // Such as extenders.
|
||||
TypeENDLOOP = 31 // Such as end of a HW loop.
|
||||
};
|
||||
@ -164,7 +183,15 @@ namespace HexagonII {
|
||||
|
||||
// Floating-point instructions.
|
||||
FPPos = 48,
|
||||
FPMask = 0x1
|
||||
FPMask = 0x1,
|
||||
|
||||
// New-Value producer-2 instructions.
|
||||
hasNewValuePos2 = 50,
|
||||
hasNewValueMask2 = 0x1,
|
||||
|
||||
// Which operand consumes or produces a new value.
|
||||
NewValueOpPos2 = 51,
|
||||
NewValueOpMask2 = 0x7
|
||||
};
|
||||
|
||||
// *** The code above must match HexagonInstrFormat*.td *** //
|
||||
@ -219,6 +246,26 @@ namespace HexagonII {
|
||||
INST_PARSE_EXTENDER = 0x00000000
|
||||
};
|
||||
|
||||
enum InstIClassBits {
|
||||
INST_ICLASS_MASK = 0xf0000000,
|
||||
INST_ICLASS_EXTENDER = 0x00000000,
|
||||
INST_ICLASS_J_1 = 0x10000000,
|
||||
INST_ICLASS_J_2 = 0x20000000,
|
||||
INST_ICLASS_LD_ST_1 = 0x30000000,
|
||||
INST_ICLASS_LD_ST_2 = 0x40000000,
|
||||
INST_ICLASS_J_3 = 0x50000000,
|
||||
INST_ICLASS_CR = 0x60000000,
|
||||
INST_ICLASS_ALU32_1 = 0x70000000,
|
||||
INST_ICLASS_XTYPE_1 = 0x80000000,
|
||||
INST_ICLASS_LD = 0x90000000,
|
||||
INST_ICLASS_ST = 0xa0000000,
|
||||
INST_ICLASS_ALU32_2 = 0xb0000000,
|
||||
INST_ICLASS_XTYPE_2 = 0xc0000000,
|
||||
INST_ICLASS_XTYPE_3 = 0xd0000000,
|
||||
INST_ICLASS_XTYPE_4 = 0xe0000000,
|
||||
INST_ICLASS_ALU32_3 = 0xf0000000
|
||||
};
|
||||
|
||||
} // End namespace HexagonII.
|
||||
|
||||
} // End namespace llvm.
|
||||
|
@ -12,13 +12,13 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonInstPrinter.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -28,63 +28,33 @@ using namespace llvm;
|
||||
#define GET_INSTRUCTION_NAME
|
||||
#include "HexagonGenAsmWriter.inc"
|
||||
|
||||
// Return the minimum value that a constant extendable operand can have
|
||||
// without being extended.
|
||||
static int getMinValue(uint64_t TSFlags) {
|
||||
unsigned isSigned =
|
||||
(TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
|
||||
unsigned bits =
|
||||
(TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
|
||||
|
||||
if (isSigned)
|
||||
return -1U << (bits - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the maximum value that a constant extendable operand can have
|
||||
// without being extended.
|
||||
static int getMaxValue(uint64_t TSFlags) {
|
||||
unsigned isSigned =
|
||||
(TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
|
||||
unsigned bits =
|
||||
(TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
|
||||
|
||||
if (isSigned)
|
||||
return ~(-1U << (bits - 1));
|
||||
|
||||
return ~(-1U << bits);
|
||||
}
|
||||
|
||||
// Return true if the instruction must be extended.
|
||||
static bool isExtended(uint64_t TSFlags) {
|
||||
return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
|
||||
}
|
||||
|
||||
// Currently just used in an assert statement
|
||||
static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED;
|
||||
// Return true if the instruction may be extended based on the operand value.
|
||||
static bool isExtendable(uint64_t TSFlags) {
|
||||
return (TSFlags >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
|
||||
HexagonInstPrinter::HexagonInstPrinter(MCAsmInfo const &MAI,
|
||||
MCInstrInfo const &MII,
|
||||
MCRegisterInfo const &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI), MII(MII), HasExtender(false) {
|
||||
}
|
||||
|
||||
StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
|
||||
return MII.getName(Opcode);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
|
||||
OS << getRegisterName(RegNo);
|
||||
void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
|
||||
O << getRegName(RegNo);
|
||||
}
|
||||
|
||||
StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
|
||||
return getRegisterName(RegNo);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::setExtender(MCInst const &MCI) {
|
||||
HasExtender = HexagonMCInstrInfo::isImmext(MCI);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printInst(MCInst const *MI, raw_ostream &OS,
|
||||
StringRef Annot,
|
||||
MCSubtargetInfo const &STI) {
|
||||
void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
|
||||
StringRef Annot, const MCSubtargetInfo &STI) {
|
||||
assert(HexagonMCInstrInfo::isBundle(*MI));
|
||||
assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
|
||||
assert(HexagonMCInstrInfo::bundleSize(*MI) > 0);
|
||||
HasExtender = false;
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
|
||||
MCInst const &MCI = *I.getInst();
|
||||
@ -116,173 +86,148 @@ void HexagonInstPrinter::printInst(MCInst const *MI, raw_ostream &OS,
|
||||
}
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
||||
void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
const MCOperand& MO = MI->getOperand(OpNo);
|
||||
|
||||
if (MO.isReg()) {
|
||||
printRegName(O, MO.getReg());
|
||||
} else if(MO.isExpr()) {
|
||||
MO.getExpr()->print(O, &MAI);
|
||||
} else if(MO.isImm()) {
|
||||
printImmOperand(MI, OpNo, O);
|
||||
} else {
|
||||
llvm_unreachable("Unknown operand");
|
||||
}
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
const MCOperand& MO = MI->getOperand(OpNo);
|
||||
|
||||
if(MO.isExpr()) {
|
||||
MO.getExpr()->print(O, &MAI);
|
||||
} else if(MO.isImm()) {
|
||||
O << MI->getOperand(OpNo).getImm();
|
||||
} else {
|
||||
llvm_unreachable("Unknown operand");
|
||||
}
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
const MCOperand &MO = MI->getOperand(OpNo);
|
||||
const MCInstrDesc &MII = getMII().get(MI->getOpcode());
|
||||
|
||||
assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
|
||||
"Expecting an extendable operand");
|
||||
|
||||
if (MO.isExpr() || isExtended(MII.TSFlags)) {
|
||||
if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo &&
|
||||
(HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)))
|
||||
O << "#";
|
||||
} else if (MO.isImm()) {
|
||||
int ImmValue = MO.getImm();
|
||||
if (ImmValue < getMinValue(MII.TSFlags) ||
|
||||
ImmValue > getMaxValue(MII.TSFlags))
|
||||
O << "#";
|
||||
MCOperand const &MO = MI->getOperand(OpNo);
|
||||
if (MO.isReg()) {
|
||||
O << getRegisterName(MO.getReg());
|
||||
} else if (MO.isExpr()) {
|
||||
int64_t Value;
|
||||
if (MO.getExpr()->evaluateAsAbsolute(Value))
|
||||
O << formatImm(Value);
|
||||
else
|
||||
O << *MO.getExpr();
|
||||
} else {
|
||||
llvm_unreachable("Unknown operand");
|
||||
}
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
printOperand(MI, OpNo, O);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI,
|
||||
unsigned OpNo, raw_ostream &O) const {
|
||||
void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI,
|
||||
unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
O << MI->getOperand(OpNo).getImm();
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
O << -MI->getOperand(OpNo).getImm();
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
O << -1;
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
int64_t Imm = MI->getOperand(OpNo).getImm();
|
||||
int64_t Imm;
|
||||
bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
|
||||
Imm = SignExtend64<9>(Imm);
|
||||
assert(Success); (void)Success;
|
||||
assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
|
||||
O << formatImm(Imm/64);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
int64_t Imm = MI->getOperand(OpNo).getImm();
|
||||
int64_t Imm;
|
||||
bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
|
||||
Imm = SignExtend64<10>(Imm);
|
||||
assert(Success); (void)Success;
|
||||
assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
|
||||
O << formatImm(Imm/128);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
int64_t Imm = MI->getOperand(OpNo).getImm();
|
||||
int64_t Imm;
|
||||
bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
|
||||
Imm = SignExtend64<10>(Imm);
|
||||
assert(Success); (void)Success;
|
||||
assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
|
||||
O << formatImm(Imm/64);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
int64_t Imm = MI->getOperand(OpNo).getImm();
|
||||
int64_t Imm;
|
||||
bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
|
||||
Imm = SignExtend64<11>(Imm);
|
||||
assert(Success); (void)Success;
|
||||
assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
|
||||
O << formatImm(Imm/128);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
const MCOperand& MO0 = MI->getOperand(OpNo);
|
||||
const MCOperand& MO1 = MI->getOperand(OpNo + 1);
|
||||
|
||||
printRegName(O, MO0.getReg());
|
||||
O << " + #" << MO1.getImm();
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
const MCOperand& MO0 = MI->getOperand(OpNo);
|
||||
const MCOperand& MO1 = MI->getOperand(OpNo + 1);
|
||||
|
||||
printRegName(O, MO0.getReg());
|
||||
O << ", #" << MO1.getImm();
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo,
|
||||
void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
|
||||
|
||||
printOperand(MI, OpNo, O);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
|
||||
void HexagonInstPrinter::printJumpTable(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
|
||||
|
||||
printOperand(MI, OpNo, O);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo,
|
||||
void HexagonInstPrinter::printConstantPool(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
|
||||
|
||||
printOperand(MI, OpNo, O);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
|
||||
void HexagonInstPrinter::printBranchOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
// Branches can take an immediate operand. This is used by the branch
|
||||
// selection pass to print $+8, an eight byte displacement from the PC.
|
||||
llvm_unreachable("Unknown branch operand.");
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
}
|
||||
void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {}
|
||||
|
||||
void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
}
|
||||
void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {}
|
||||
|
||||
void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
}
|
||||
void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {}
|
||||
|
||||
void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
|
||||
void HexagonInstPrinter::printSymbol(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O, bool hi) const {
|
||||
assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
|
||||
MCOperand const &MO = MI->getOperand(OpNo);
|
||||
|
||||
O << '#' << (hi ? "HI" : "LO") << "(#";
|
||||
printOperand(MI, OpNo, O);
|
||||
O << '#' << (hi ? "HI" : "LO") << '(';
|
||||
if (MO.isImm()) {
|
||||
O << '#';
|
||||
printOperand(MI, OpNo, O);
|
||||
} else {
|
||||
printOperand(MI, OpNo, O);
|
||||
assert("Unknown symbol operand");
|
||||
}
|
||||
O << ')';
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printExtBrtarget(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
const MCOperand &MO = MI->getOperand(OpNo);
|
||||
const MCInstrDesc &MII = getMII().get(MI->getOpcode());
|
||||
|
||||
assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
|
||||
"Expecting an extendable operand");
|
||||
|
||||
if (MO.isExpr() || isExtended(MII.TSFlags)) {
|
||||
O << "##";
|
||||
void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
MCOperand const &MO = MI->getOperand(OpNo);
|
||||
assert (MO.isExpr());
|
||||
MCExpr const &Expr = *MO.getExpr();
|
||||
int64_t Value;
|
||||
if (Expr.evaluateAsAbsolute(Value))
|
||||
O << format("0x%" PRIx64, Value);
|
||||
else {
|
||||
if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))
|
||||
if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo)
|
||||
O << "##";
|
||||
O << Expr;
|
||||
}
|
||||
printOperand(MI, OpNo, O);
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class prints an Hexagon MCInst to a .s file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -15,7 +14,6 @@
|
||||
#define LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H
|
||||
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
/// Prints bundles as a newline separated list of individual instructions
|
||||
@ -25,76 +23,69 @@ namespace llvm {
|
||||
/// r0 = add(r1, r2)
|
||||
/// r0 = #0 \v jump 0x0
|
||||
/// :endloop0 :endloop1
|
||||
class HexagonInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
explicit HexagonInstPrinter(MCAsmInfo const &MAI,
|
||||
MCInstrInfo const &MII,
|
||||
MCRegisterInfo const &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI), MII(MII) {}
|
||||
class HexagonInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
explicit HexagonInstPrinter(MCAsmInfo const &MAI, MCInstrInfo const &MII,
|
||||
MCRegisterInfo const &MRI);
|
||||
void printInst(MCInst const *MI, raw_ostream &O, StringRef Annot,
|
||||
const MCSubtargetInfo &STI) override;
|
||||
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
||||
void printInstruction(MCInst const *MI, raw_ostream &O);
|
||||
|
||||
void printInst(MCInst const *MI, raw_ostream &O, StringRef Annot,
|
||||
const MCSubtargetInfo &STI) override;
|
||||
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
||||
void printInstruction(const MCInst *MI, raw_ostream &O);
|
||||
void printRegName(raw_ostream &OS, unsigned RegNo) const override;
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
StringRef getRegName(unsigned RegNo) const;
|
||||
static char const *getRegisterName(unsigned RegNo);
|
||||
void printRegName(raw_ostream &O, unsigned RegNo) const override;
|
||||
|
||||
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
void printImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
void printExtOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
void printUnsignedImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printNegImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
|
||||
const;
|
||||
void printNOneImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
|
||||
const;
|
||||
void prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printMEMriOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
|
||||
const;
|
||||
void printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
|
||||
const;
|
||||
void printCallOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
|
||||
const;
|
||||
void printAbsAddrOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
|
||||
const;
|
||||
void printPredicateOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
|
||||
const;
|
||||
void printGlobalOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
|
||||
const;
|
||||
void printJumpTable(const MCInst *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
void printExtBrtarget(const MCInst *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
|
||||
void printConstantPool(const MCInst *MI, unsigned OpNo,
|
||||
void printOperand(MCInst const *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
void printExtOperand(MCInst const *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
void printUnsignedImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printNegImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printNOneImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printBranchOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printCallOperand(MCInst const *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
void printAbsAddrOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printPredicateOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printGlobalOperand(MCInst const *MI, unsigned OpNo,
|
||||
raw_ostream &O) const;
|
||||
void printJumpTable(MCInst const *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
void printBrtarget(MCInst const *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
|
||||
void printSymbolHi(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
|
||||
{ printSymbol(MI, OpNo, O, true); }
|
||||
void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
|
||||
{ printSymbol(MI, OpNo, O, false); }
|
||||
void printConstantPool(MCInst const *MI, unsigned OpNo, raw_ostream &O) const;
|
||||
|
||||
const MCInstrInfo &getMII() const {
|
||||
return MII;
|
||||
}
|
||||
void printSymbolHi(MCInst const *MI, unsigned OpNo, raw_ostream &O) const {
|
||||
printSymbol(MI, OpNo, O, true);
|
||||
}
|
||||
void printSymbolLo(MCInst const *MI, unsigned OpNo, raw_ostream &O) const {
|
||||
printSymbol(MI, OpNo, O, false);
|
||||
}
|
||||
|
||||
protected:
|
||||
void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi)
|
||||
const;
|
||||
MCAsmInfo const &getMAI() const { return MAI; }
|
||||
MCInstrInfo const &getMII() const { return MII; }
|
||||
|
||||
private:
|
||||
const MCInstrInfo &MII;
|
||||
protected:
|
||||
void printSymbol(MCInst const *MI, unsigned OpNo, raw_ostream &O,
|
||||
bool hi) const;
|
||||
|
||||
bool HasExtender;
|
||||
void setExtender(MCInst const &MCI);
|
||||
};
|
||||
private:
|
||||
MCInstrInfo const &MII;
|
||||
|
||||
bool HasExtender;
|
||||
void setExtender(MCInst const &MCI);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
580
lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
Normal file
580
lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
Normal file
@ -0,0 +1,580 @@
|
||||
//===----- HexagonMCChecker.cpp - Instruction bundle checking -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This implements the checking of insns inside a bundle according to the
|
||||
// packet constraint rules of the Hexagon ISA.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonMCChecker.h"
|
||||
|
||||
#include "HexagonBaseInfo.h"
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<bool> RelaxNVChecks("relax-nv-checks", cl::init(false),
|
||||
cl::ZeroOrMore, cl::Hidden, cl::desc("Relax checks of new-value validity"));
|
||||
|
||||
const HexagonMCChecker::PredSense
|
||||
HexagonMCChecker::Unconditional(Hexagon::NoRegister, false);
|
||||
|
||||
void HexagonMCChecker::init() {
|
||||
// Initialize read-only registers set.
|
||||
ReadOnly.insert(Hexagon::PC);
|
||||
|
||||
// Figure out the loop-registers definitions.
|
||||
if (HexagonMCInstrInfo::isInnerLoop(MCB)) {
|
||||
Defs[Hexagon::SA0].insert(Unconditional); // FIXME: define or change SA0?
|
||||
Defs[Hexagon::LC0].insert(Unconditional);
|
||||
}
|
||||
if (HexagonMCInstrInfo::isOuterLoop(MCB)) {
|
||||
Defs[Hexagon::SA1].insert(Unconditional); // FIXME: define or change SA0?
|
||||
Defs[Hexagon::LC1].insert(Unconditional);
|
||||
}
|
||||
|
||||
if (HexagonMCInstrInfo::isBundle(MCB))
|
||||
// Unfurl a bundle.
|
||||
for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
|
||||
init(*I.getInst());
|
||||
}
|
||||
else
|
||||
init(MCB);
|
||||
}
|
||||
|
||||
void HexagonMCChecker::init(MCInst const& MCI) {
|
||||
const MCInstrDesc& MCID = HexagonMCInstrInfo::getDesc(MCII, MCI);
|
||||
unsigned PredReg = Hexagon::NoRegister;
|
||||
bool isTrue = false;
|
||||
|
||||
// Get used registers.
|
||||
for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
|
||||
if (MCI.getOperand(i).isReg()) {
|
||||
unsigned R = MCI.getOperand(i).getReg();
|
||||
|
||||
if (HexagonMCInstrInfo::isPredicated(MCII, MCI) && isPredicateRegister(R)) {
|
||||
// Note an used predicate register.
|
||||
PredReg = R;
|
||||
isTrue = HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI);
|
||||
|
||||
// Note use of new predicate register.
|
||||
if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
|
||||
NewPreds.insert(PredReg);
|
||||
}
|
||||
else
|
||||
// Note register use. Super-registers are not tracked directly,
|
||||
// but their components.
|
||||
for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
|
||||
SRI.isValid();
|
||||
++SRI)
|
||||
if (!MCSubRegIterator(*SRI, &RI).isValid())
|
||||
// Skip super-registers used indirectly.
|
||||
Uses.insert(*SRI);
|
||||
}
|
||||
|
||||
// Get implicit register definitions.
|
||||
const uint16_t* ImpDefs = MCID.getImplicitDefs();
|
||||
for (unsigned i = 0; i < MCID.getNumImplicitDefs(); ++i) {
|
||||
unsigned R = ImpDefs[i];
|
||||
|
||||
if (Hexagon::R31 != R && MCID.isCall())
|
||||
// Any register other than the LR and the PC are actually volatile ones
|
||||
// as defined by the ABI, not modified implicitly by the call insn.
|
||||
continue;
|
||||
if (Hexagon::PC == R)
|
||||
// Branches are the only insns that can change the PC,
|
||||
// otherwise a read-only register.
|
||||
continue;
|
||||
|
||||
if (Hexagon::USR_OVF == R)
|
||||
// Many insns change the USR implicitly, but only one or another flag.
|
||||
// The instruction table models the USR.OVF flag, which can be implicitly
|
||||
// modified more than once, but cannot be modified in the same packet
|
||||
// with an instruction that modifies is explicitly. Deal with such situ-
|
||||
// ations individually.
|
||||
SoftDefs.insert(R);
|
||||
else if (isPredicateRegister(R) && HexagonMCInstrInfo::isPredicateLate(MCII, MCI))
|
||||
// Include implicit late predicates.
|
||||
LatePreds.insert(R);
|
||||
else
|
||||
Defs[R].insert(PredSense(PredReg, isTrue));
|
||||
}
|
||||
|
||||
// Figure out explicit register definitions.
|
||||
for (unsigned i = 0; i < MCID.getNumDefs(); ++i) {
|
||||
unsigned R = MCI.getOperand(i).getReg(),
|
||||
S = Hexagon::NoRegister;
|
||||
|
||||
// Note register definitions, direct ones as well as indirect side-effects.
|
||||
// Super-registers are not tracked directly, but their components.
|
||||
for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
|
||||
SRI.isValid();
|
||||
++SRI) {
|
||||
if (MCSubRegIterator(*SRI, &RI).isValid())
|
||||
// Skip super-registers defined indirectly.
|
||||
continue;
|
||||
|
||||
if (R == *SRI) {
|
||||
if (S == R)
|
||||
// Avoid scoring the defined register multiple times.
|
||||
continue;
|
||||
else
|
||||
// Note that the defined register has already been scored.
|
||||
S = R;
|
||||
}
|
||||
|
||||
if (Hexagon::P3_0 != R && Hexagon::P3_0 == *SRI)
|
||||
// P3:0 is a special case, since multiple predicate register definitions
|
||||
// in a packet is allowed as the equivalent of their logical "and".
|
||||
// Only an explicit definition of P3:0 is noted as such; if a
|
||||
// side-effect, then note as a soft definition.
|
||||
SoftDefs.insert(*SRI);
|
||||
else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) && isPredicateRegister(*SRI))
|
||||
// Some insns produce predicates too late to be used in the same packet.
|
||||
LatePreds.insert(*SRI);
|
||||
else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCVI_VM_CUR_LD)
|
||||
// Current loads should be used in the same packet.
|
||||
// TODO: relies on the impossibility of a current and a temporary loads
|
||||
// in the same packet.
|
||||
CurDefs.insert(*SRI), Defs[*SRI].insert(PredSense(PredReg, isTrue));
|
||||
else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCVI_VM_TMP_LD)
|
||||
// Temporary loads should be used in the same packet, but don't commit
|
||||
// results, so it should be disregarded if another insn changes the same
|
||||
// register.
|
||||
// TODO: relies on the impossibility of a current and a temporary loads
|
||||
// in the same packet.
|
||||
TmpDefs.insert(*SRI);
|
||||
else if (i <= 1 && llvm::HexagonMCInstrInfo::hasNewValue2(MCII, MCI) )
|
||||
// vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and
|
||||
// destination registers with this instruction. same for vdeal(Vx,Vy,Rx)
|
||||
Uses.insert(*SRI);
|
||||
else
|
||||
Defs[*SRI].insert(PredSense(PredReg, isTrue));
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out register definitions that produce new values.
|
||||
if (HexagonMCInstrInfo::hasNewValue(MCII, MCI)) {
|
||||
unsigned R = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg();
|
||||
|
||||
if (HexagonMCInstrInfo::isCompound(MCII, MCI))
|
||||
compoundRegisterMap(R); // Compound insns have a limited register range.
|
||||
|
||||
for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
|
||||
SRI.isValid();
|
||||
++SRI)
|
||||
if (!MCSubRegIterator(*SRI, &RI).isValid())
|
||||
// No super-registers defined indirectly.
|
||||
NewDefs[*SRI].push_back(NewSense::Def(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
|
||||
HexagonMCInstrInfo::isFloat(MCII, MCI)));
|
||||
|
||||
// For fairly unique 2-dot-new producers, example:
|
||||
// vdeal(V1, V9, R0) V1.new and V9.new can be used by consumers.
|
||||
if (HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) {
|
||||
unsigned R2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, MCI).getReg();
|
||||
|
||||
for(MCRegAliasIterator SRI(R2, &RI, !MCSubRegIterator(R2, &RI).isValid());
|
||||
SRI.isValid();
|
||||
++SRI)
|
||||
if (!MCSubRegIterator(*SRI, &RI).isValid())
|
||||
NewDefs[*SRI].push_back(NewSense::Def(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
|
||||
HexagonMCInstrInfo::isFloat(MCII, MCI)));
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out definitions of new predicate registers.
|
||||
if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
|
||||
for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
|
||||
if (MCI.getOperand(i).isReg()) {
|
||||
unsigned P = MCI.getOperand(i).getReg();
|
||||
|
||||
if (isPredicateRegister(P))
|
||||
NewPreds.insert(P);
|
||||
}
|
||||
|
||||
// Figure out uses of new values.
|
||||
if (HexagonMCInstrInfo::isNewValue(MCII, MCI)) {
|
||||
unsigned N = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg();
|
||||
|
||||
if (!MCSubRegIterator(N, &RI).isValid()) {
|
||||
// Super-registers cannot use new values.
|
||||
if (MCID.isBranch())
|
||||
NewUses[N] = NewSense::Jmp(llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV);
|
||||
else
|
||||
NewUses[N] = NewSense::Use(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HexagonMCChecker::HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &mcb, MCInst &mcbdx,
|
||||
MCRegisterInfo const &ri)
|
||||
: MCB(mcb), MCBDX(mcbdx), RI(ri), MCII(MCII), STI(STI),
|
||||
bLoadErrInfo(false) {
|
||||
init();
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::check() {
|
||||
bool chkB = checkBranches();
|
||||
bool chkP = checkPredicates();
|
||||
bool chkNV = checkNewValues();
|
||||
bool chkR = checkRegisters();
|
||||
bool chkS = checkSolo();
|
||||
bool chkSh = checkShuffle();
|
||||
bool chkSl = checkSlots();
|
||||
bool chk = chkB && chkP && chkNV && chkR && chkS && chkSh && chkSl;
|
||||
|
||||
return chk;
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::checkSlots()
|
||||
|
||||
{
|
||||
unsigned slotsUsed = 0;
|
||||
for (auto HMI: HexagonMCInstrInfo::bundleInstructions(MCBDX)) {
|
||||
MCInst const& MCI = *HMI.getInst();
|
||||
if (HexagonMCInstrInfo::isImmext(MCI))
|
||||
continue;
|
||||
if (HexagonMCInstrInfo::isDuplex(MCII, MCI))
|
||||
slotsUsed += 2;
|
||||
else
|
||||
++slotsUsed;
|
||||
}
|
||||
|
||||
if (slotsUsed > HEXAGON_PACKET_SIZE) {
|
||||
HexagonMCErrInfo errInfo;
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NOSLOTS);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check legal use of branches.
|
||||
bool HexagonMCChecker::checkBranches() {
|
||||
HexagonMCErrInfo errInfo;
|
||||
if (HexagonMCInstrInfo::isBundle(MCB)) {
|
||||
bool hasConditional = false;
|
||||
unsigned Branches = 0, Returns = 0, NewIndirectBranches = 0,
|
||||
NewValueBranches = 0, Conditional = HEXAGON_PRESHUFFLE_PACKET_SIZE,
|
||||
Unconditional = HEXAGON_PRESHUFFLE_PACKET_SIZE;
|
||||
|
||||
for (unsigned i = HexagonMCInstrInfo::bundleInstructionsOffset;
|
||||
i < MCB.size(); ++i) {
|
||||
MCInst const &MCI = *MCB.begin()[i].getInst();
|
||||
|
||||
if (HexagonMCInstrInfo::isImmext(MCI))
|
||||
continue;
|
||||
if (HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch() ||
|
||||
HexagonMCInstrInfo::getDesc(MCII, MCI).isCall()) {
|
||||
++Branches;
|
||||
if (HexagonMCInstrInfo::getDesc(MCII, MCI).isIndirectBranch() &&
|
||||
HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
|
||||
++NewIndirectBranches;
|
||||
if (HexagonMCInstrInfo::isNewValue(MCII, MCI))
|
||||
++NewValueBranches;
|
||||
|
||||
if (HexagonMCInstrInfo::isPredicated(MCII, MCI) ||
|
||||
HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) {
|
||||
hasConditional = true;
|
||||
Conditional = i; // Record the position of the conditional branch.
|
||||
} else {
|
||||
Unconditional = i; // Record the position of the unconditional branch.
|
||||
}
|
||||
}
|
||||
if (HexagonMCInstrInfo::getDesc(MCII, MCI).isReturn() &&
|
||||
HexagonMCInstrInfo::getDesc(MCII, MCI).mayLoad())
|
||||
++Returns;
|
||||
}
|
||||
|
||||
if (Branches) // FIXME: should "Defs.count(Hexagon::PC)" be here too?
|
||||
if (HexagonMCInstrInfo::isInnerLoop(MCB) ||
|
||||
HexagonMCInstrInfo::isOuterLoop(MCB)) {
|
||||
// Error out if there's any branch in a loop-end packet.
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_ENDLOOP, Hexagon::PC);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
if (Branches > 1)
|
||||
if (!hasConditional || Conditional > Unconditional) {
|
||||
// Error out if more than one unconditional branch or
|
||||
// the conditional branch appears after the unconditional one.
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_BRANCHES);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check legal use of predicate registers.
|
||||
bool HexagonMCChecker::checkPredicates() {
|
||||
HexagonMCErrInfo errInfo;
|
||||
// Check for proper use of new predicate registers.
|
||||
for (const auto& I : NewPreds) {
|
||||
unsigned P = I;
|
||||
|
||||
if (!Defs.count(P) || LatePreds.count(P)) {
|
||||
// Error out if the new predicate register is not defined,
|
||||
// or defined "late"
|
||||
// (e.g., "{ if (p3.new)... ; p3 = sp1loop0(#r7:2, Rs) }").
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWP, P);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for proper use of auto-anded of predicate registers.
|
||||
for (const auto& I : LatePreds) {
|
||||
unsigned P = I;
|
||||
|
||||
if (LatePreds.count(P) > 1 || Defs.count(P)) {
|
||||
// Error out if predicate register defined "late" multiple times or
|
||||
// defined late and regularly defined
|
||||
// (e.g., "{ p3 = sp1loop0(...); p3 = cmp.eq(...) }".
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, P);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check legal use of new values.
|
||||
bool HexagonMCChecker::checkNewValues() {
|
||||
HexagonMCErrInfo errInfo;
|
||||
memset(&errInfo, 0, sizeof(errInfo));
|
||||
for (auto& I : NewUses) {
|
||||
unsigned R = I.first;
|
||||
NewSense &US = I.second;
|
||||
|
||||
if (!hasValidNewValueDef(US, NewDefs[R])) {
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWV, R);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for legal register uses and definitions.
|
||||
bool HexagonMCChecker::checkRegisters() {
|
||||
HexagonMCErrInfo errInfo;
|
||||
// Check for proper register definitions.
|
||||
for (const auto& I : Defs) {
|
||||
unsigned R = I.first;
|
||||
|
||||
if (ReadOnly.count(R)) {
|
||||
// Error out for definitions of read-only registers.
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_READONLY, R);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
if (isLoopRegister(R) && Defs.count(R) > 1 &&
|
||||
(HexagonMCInstrInfo::isInnerLoop(MCB) ||
|
||||
HexagonMCInstrInfo::isOuterLoop(MCB))) {
|
||||
// Error out for definitions of loop registers at the end of a loop.
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_LOOP, R);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
if (SoftDefs.count(R)) {
|
||||
// Error out for explicit changes to registers also weakly defined
|
||||
// (e.g., "{ usr = r0; r0 = sfadd(...) }").
|
||||
unsigned UsrR = Hexagon::USR; // Silence warning about mixed types in ?:.
|
||||
unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
if (!isPredicateRegister(R) && Defs[R].size() > 1) {
|
||||
// Check for multiple register definitions.
|
||||
PredSet &PM = Defs[R];
|
||||
|
||||
// Check for multiple unconditional register definitions.
|
||||
if (PM.count(Unconditional)) {
|
||||
// Error out on an unconditional change when there are any other
|
||||
// changes, conditional or not.
|
||||
unsigned UsrR = Hexagon::USR;
|
||||
unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
// Check for multiple conditional register definitions.
|
||||
for (const auto& J : PM) {
|
||||
PredSense P = J;
|
||||
|
||||
// Check for multiple uses of the same condition.
|
||||
if (PM.count(P) > 1) {
|
||||
// Error out on conditional changes based on the same predicate
|
||||
// (e.g., "{ if (!p0) r0 =...; if (!p0) r0 =... }").
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
// Check for the use of the complementary condition.
|
||||
P.second = !P.second;
|
||||
if (PM.count(P) && PM.size() > 2) {
|
||||
// Error out on conditional changes based on the same predicate
|
||||
// multiple times
|
||||
// (e.g., "{ if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0 =... }").
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for use of current definitions.
|
||||
for (const auto& I : CurDefs) {
|
||||
unsigned R = I;
|
||||
|
||||
if (!Uses.count(R)) {
|
||||
// Warn on an unused current definition.
|
||||
errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_CURRENT, R);
|
||||
addErrInfo(errInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for use of temporary definitions.
|
||||
for (const auto& I : TmpDefs) {
|
||||
unsigned R = I;
|
||||
|
||||
if (!Uses.count(R)) {
|
||||
// special case for vhist
|
||||
bool vHistFound = false;
|
||||
for (auto const&HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
|
||||
if(llvm::HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) == HexagonII::TypeCVI_HIST) {
|
||||
vHistFound = true; // vhist() implicitly uses ALL REGxx.tmp
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Warn on an unused temporary definition.
|
||||
if (vHistFound == false) {
|
||||
errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_TEMPORARY, R);
|
||||
addErrInfo(errInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for legal use of solo insns.
|
||||
bool HexagonMCChecker::checkSolo() {
|
||||
HexagonMCErrInfo errInfo;
|
||||
if (HexagonMCInstrInfo::isBundle(MCB) &&
|
||||
HexagonMCInstrInfo::bundleSize(MCB) > 1) {
|
||||
for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
|
||||
if (llvm::HexagonMCInstrInfo::isSolo(MCII, *I.getInst())) {
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SOLO);
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::checkShuffle() {
|
||||
HexagonMCErrInfo errInfo;
|
||||
// Branch info is lost when duplexing. The unduplexed insns must be
|
||||
// checked and only branch errors matter for this case.
|
||||
HexagonMCShuffler MCS(MCII, STI, MCB);
|
||||
if (!MCS.check()) {
|
||||
if (MCS.getError() == HexagonShuffler::SHUFFLE_ERROR_BRANCHES) {
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE);
|
||||
errInfo.setShuffleError(MCS.getError());
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
HexagonMCShuffler MCSDX(MCII, STI, MCBDX);
|
||||
if (!MCSDX.check()) {
|
||||
errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE);
|
||||
errInfo.setShuffleError(MCSDX.getError());
|
||||
addErrInfo(errInfo);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HexagonMCChecker::compoundRegisterMap(unsigned& Register) {
|
||||
switch (Register) {
|
||||
default:
|
||||
break;
|
||||
case Hexagon::R15:
|
||||
Register = Hexagon::R23;
|
||||
break;
|
||||
case Hexagon::R14:
|
||||
Register = Hexagon::R22;
|
||||
break;
|
||||
case Hexagon::R13:
|
||||
Register = Hexagon::R21;
|
||||
break;
|
||||
case Hexagon::R12:
|
||||
Register = Hexagon::R20;
|
||||
break;
|
||||
case Hexagon::R11:
|
||||
Register = Hexagon::R19;
|
||||
break;
|
||||
case Hexagon::R10:
|
||||
Register = Hexagon::R18;
|
||||
break;
|
||||
case Hexagon::R9:
|
||||
Register = Hexagon::R17;
|
||||
break;
|
||||
case Hexagon::R8:
|
||||
Register = Hexagon::R16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::hasValidNewValueDef(const NewSense &Use,
|
||||
const NewSenseList &Defs) const {
|
||||
bool Strict = !RelaxNVChecks;
|
||||
|
||||
for (unsigned i = 0, n = Defs.size(); i < n; ++i) {
|
||||
const NewSense &Def = Defs[i];
|
||||
// NVJ cannot use a new FP value [7.6.1]
|
||||
if (Use.IsNVJ && (Def.IsFloat || Def.PredReg != 0))
|
||||
continue;
|
||||
// If the definition was not predicated, then it does not matter if
|
||||
// the use is.
|
||||
if (Def.PredReg == 0)
|
||||
return true;
|
||||
// With the strict checks, both the definition and the use must be
|
||||
// predicated on the same register and condition.
|
||||
if (Strict) {
|
||||
if (Def.PredReg == Use.PredReg && Def.Cond == Use.Cond)
|
||||
return true;
|
||||
} else {
|
||||
// With the relaxed checks, if the definition was predicated, the only
|
||||
// detectable violation is if the use is predicated on the opposing
|
||||
// condition, otherwise, it's ok.
|
||||
if (Def.PredReg != Use.PredReg || Def.Cond == Use.Cond)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
218
lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
Normal file
218
lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
Normal file
@ -0,0 +1,218 @@
|
||||
//===----- HexagonMCChecker.h - Instruction bundle checking ---------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This implements the checking of insns inside a bundle according to the
|
||||
// packet constraint rules of the Hexagon ISA.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HEXAGONMCCHECKER_H
|
||||
#define HEXAGONMCCHECKER_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <queue>
|
||||
#include "MCTargetDesc/HexagonMCShuffler.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
class MCOperandInfo;
|
||||
|
||||
typedef struct {
|
||||
unsigned Error, Warning, ShuffleError;
|
||||
unsigned Register;
|
||||
} ErrInfo_T;
|
||||
|
||||
class HexagonMCErrInfo {
|
||||
public:
|
||||
enum {
|
||||
CHECK_SUCCESS = 0,
|
||||
// Errors.
|
||||
CHECK_ERROR_BRANCHES = 0x00001,
|
||||
CHECK_ERROR_NEWP = 0x00002,
|
||||
CHECK_ERROR_NEWV = 0x00004,
|
||||
CHECK_ERROR_REGISTERS = 0x00008,
|
||||
CHECK_ERROR_READONLY = 0x00010,
|
||||
CHECK_ERROR_LOOP = 0x00020,
|
||||
CHECK_ERROR_ENDLOOP = 0x00040,
|
||||
CHECK_ERROR_SOLO = 0x00080,
|
||||
CHECK_ERROR_SHUFFLE = 0x00100,
|
||||
CHECK_ERROR_NOSLOTS = 0x00200,
|
||||
CHECK_ERROR_UNKNOWN = 0x00400,
|
||||
// Warnings.
|
||||
CHECK_WARN_CURRENT = 0x10000,
|
||||
CHECK_WARN_TEMPORARY = 0x20000
|
||||
};
|
||||
ErrInfo_T s;
|
||||
|
||||
void reset() {
|
||||
s.Error = CHECK_SUCCESS;
|
||||
s.Warning = CHECK_SUCCESS;
|
||||
s.ShuffleError = HexagonShuffler::SHUFFLE_SUCCESS;
|
||||
s.Register = Hexagon::NoRegister;
|
||||
};
|
||||
HexagonMCErrInfo() {
|
||||
reset();
|
||||
};
|
||||
|
||||
void setError(unsigned e, unsigned r = Hexagon::NoRegister)
|
||||
{ s.Error = e; s.Register = r; };
|
||||
void setWarning(unsigned w, unsigned r = Hexagon::NoRegister)
|
||||
{ s.Warning = w; s.Register = r; };
|
||||
void setShuffleError(unsigned e) { s.ShuffleError = e; };
|
||||
};
|
||||
|
||||
/// Check for a valid bundle.
|
||||
class HexagonMCChecker {
|
||||
/// Insn bundle.
|
||||
MCInst& MCB;
|
||||
MCInst& MCBDX;
|
||||
const MCRegisterInfo& RI;
|
||||
MCInstrInfo const &MCII;
|
||||
MCSubtargetInfo const &STI;
|
||||
bool bLoadErrInfo;
|
||||
|
||||
/// Set of definitions: register #, if predicated, if predicated true.
|
||||
typedef std::pair<unsigned, bool> PredSense;
|
||||
static const PredSense Unconditional;
|
||||
typedef std::multiset<PredSense> PredSet;
|
||||
typedef std::multiset<PredSense>::iterator PredSetIterator;
|
||||
|
||||
typedef llvm::DenseMap<unsigned, PredSet>::iterator DefsIterator;
|
||||
llvm::DenseMap<unsigned, PredSet> Defs;
|
||||
|
||||
/// Information about how a new-value register is defined or used:
|
||||
/// PredReg = predicate register, 0 if use/def not predicated,
|
||||
/// Cond = true/false for if(PredReg)/if(!PredReg) respectively,
|
||||
/// IsFloat = true if definition produces a floating point value
|
||||
/// (not valid for uses),
|
||||
/// IsNVJ = true if the use is a new-value branch (not valid for
|
||||
/// definitions).
|
||||
struct NewSense {
|
||||
unsigned PredReg;
|
||||
bool IsFloat, IsNVJ, Cond;
|
||||
// The special-case "constructors":
|
||||
static NewSense Jmp(bool isNVJ) {
|
||||
NewSense NS = { /*PredReg=*/ 0, /*IsFloat=*/ false, /*IsNVJ=*/ isNVJ,
|
||||
/*Cond=*/ false };
|
||||
return NS;
|
||||
}
|
||||
static NewSense Use(unsigned PR, bool True) {
|
||||
NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ false, /*IsNVJ=*/ false,
|
||||
/*Cond=*/ True };
|
||||
return NS;
|
||||
}
|
||||
static NewSense Def(unsigned PR, bool True, bool Float) {
|
||||
NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ Float, /*IsNVJ=*/ false,
|
||||
/*Cond=*/ True };
|
||||
return NS;
|
||||
}
|
||||
};
|
||||
/// Set of definitions that produce new register:
|
||||
typedef llvm::SmallVector<NewSense,2> NewSenseList;
|
||||
typedef llvm::DenseMap<unsigned, NewSenseList>::iterator NewDefsIterator;
|
||||
llvm::DenseMap<unsigned, NewSenseList> NewDefs;
|
||||
|
||||
/// Set of weak definitions whose clashes should be enforced selectively.
|
||||
typedef std::set<unsigned>::iterator SoftDefsIterator;
|
||||
std::set<unsigned> SoftDefs;
|
||||
|
||||
/// Set of current definitions committed to the register file.
|
||||
typedef std::set<unsigned>::iterator CurDefsIterator;
|
||||
std::set<unsigned> CurDefs;
|
||||
|
||||
/// Set of temporary definitions not committed to the register file.
|
||||
typedef std::set<unsigned>::iterator TmpDefsIterator;
|
||||
std::set<unsigned> TmpDefs;
|
||||
|
||||
/// Set of new predicates used.
|
||||
typedef std::set<unsigned>::iterator NewPredsIterator;
|
||||
std::set<unsigned> NewPreds;
|
||||
|
||||
/// Set of predicates defined late.
|
||||
typedef std::multiset<unsigned>::iterator LatePredsIterator;
|
||||
std::multiset<unsigned> LatePreds;
|
||||
|
||||
/// Set of uses.
|
||||
typedef std::set<unsigned>::iterator UsesIterator;
|
||||
std::set<unsigned> Uses;
|
||||
|
||||
/// Set of new values used: new register, if new-value jump.
|
||||
typedef llvm::DenseMap<unsigned, NewSense>::iterator NewUsesIterator;
|
||||
llvm::DenseMap<unsigned, NewSense> NewUses;
|
||||
|
||||
/// Pre-defined set of read-only registers.
|
||||
typedef std::set<unsigned>::iterator ReadOnlyIterator;
|
||||
std::set<unsigned> ReadOnly;
|
||||
|
||||
std::queue<ErrInfo_T> ErrInfoQ;
|
||||
HexagonMCErrInfo CrntErrInfo;
|
||||
|
||||
void getErrInfo() {
|
||||
if (bLoadErrInfo == true) {
|
||||
if (ErrInfoQ.empty()) {
|
||||
CrntErrInfo.reset();
|
||||
} else {
|
||||
CrntErrInfo.s = ErrInfoQ.front();
|
||||
ErrInfoQ.pop();
|
||||
}
|
||||
}
|
||||
bLoadErrInfo = false;
|
||||
}
|
||||
|
||||
void init();
|
||||
void init(MCInst const&);
|
||||
|
||||
// Checks performed.
|
||||
bool checkBranches();
|
||||
bool checkPredicates();
|
||||
bool checkNewValues();
|
||||
bool checkRegisters();
|
||||
bool checkSolo();
|
||||
bool checkShuffle();
|
||||
bool checkSlots();
|
||||
|
||||
static void compoundRegisterMap(unsigned&);
|
||||
|
||||
bool isPredicateRegister(unsigned R) const {
|
||||
return (Hexagon::P0 == R || Hexagon::P1 == R ||
|
||||
Hexagon::P2 == R || Hexagon::P3 == R);
|
||||
};
|
||||
bool isLoopRegister(unsigned R) const {
|
||||
return (Hexagon::SA0 == R || Hexagon::LC0 == R ||
|
||||
Hexagon::SA1 == R || Hexagon::LC1 == R);
|
||||
};
|
||||
|
||||
bool hasValidNewValueDef(const NewSense &Use,
|
||||
const NewSenseList &Defs) const;
|
||||
|
||||
public:
|
||||
explicit HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst& mcb, MCInst &mcbdx,
|
||||
const MCRegisterInfo& ri);
|
||||
|
||||
bool check();
|
||||
|
||||
/// add a new error/warning
|
||||
void addErrInfo(HexagonMCErrInfo &err) { ErrInfoQ.push(err.s); };
|
||||
|
||||
/// Return the error code for the last operation in the insn bundle.
|
||||
unsigned getError() { getErrInfo(); return CrntErrInfo.s.Error; };
|
||||
unsigned getWarning() { getErrInfo(); return CrntErrInfo.s.Warning; };
|
||||
unsigned getShuffleError() { getErrInfo(); return CrntErrInfo.s.ShuffleError; };
|
||||
unsigned getErrRegister() { getErrInfo(); return CrntErrInfo.s.Register; };
|
||||
bool getNextErrInfo() {
|
||||
bLoadErrInfo = true;
|
||||
return (ErrInfoQ.empty()) ? false : (getErrInfo(), true);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HEXAGONMCCHECKER_H
|
@ -195,15 +195,13 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
// Special case this one from Group L2.
|
||||
// Rd = memw(r29+#u5:2)
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
|
||||
if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
|
||||
MCI.getOperand(2).isImm() &&
|
||||
isShiftedUInt<5, 2>(MCI.getOperand(2).getImm())) {
|
||||
if (HexagonMCInstrInfo::isIntReg(SrcReg) &&
|
||||
Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {
|
||||
return HexagonII::HSIG_L2;
|
||||
}
|
||||
// Rd = memw(Rs+#u4:2)
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
(MCI.getOperand(2).isImm() &&
|
||||
isShiftedUInt<4, 2>(MCI.getOperand(2).getImm()))) {
|
||||
inRange<4, 2>(MCI, 2)) {
|
||||
return HexagonII::HSIG_L1;
|
||||
}
|
||||
}
|
||||
@ -214,7 +212,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
SrcReg = MCI.getOperand(1).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
MCI.getOperand(2).isImm() && isUInt<4>(MCI.getOperand(2).getImm())) {
|
||||
inRange<4>(MCI, 2)) {
|
||||
return HexagonII::HSIG_L1;
|
||||
}
|
||||
break;
|
||||
@ -235,8 +233,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
SrcReg = MCI.getOperand(1).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
MCI.getOperand(2).isImm() &&
|
||||
isShiftedUInt<3, 1>(MCI.getOperand(2).getImm())) {
|
||||
inRange<3, 1>(MCI, 2)) {
|
||||
return HexagonII::HSIG_L2;
|
||||
}
|
||||
break;
|
||||
@ -246,7 +243,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
SrcReg = MCI.getOperand(1).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
MCI.getOperand(2).isImm() && isUInt<3>(MCI.getOperand(2).getImm())) {
|
||||
inRange<3>(MCI, 2)) {
|
||||
return HexagonII::HSIG_L2;
|
||||
}
|
||||
break;
|
||||
@ -256,8 +253,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
SrcReg = MCI.getOperand(1).getReg();
|
||||
if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
|
||||
HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
|
||||
MCI.getOperand(2).isImm() &&
|
||||
isShiftedUInt<5, 3>(MCI.getOperand(2).getImm())) {
|
||||
inRange<5, 3>(MCI, 2)) {
|
||||
return HexagonII::HSIG_L2;
|
||||
}
|
||||
break;
|
||||
@ -326,15 +322,13 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
Src2Reg = MCI.getOperand(2).getReg();
|
||||
if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
|
||||
Hexagon::R29 == Src1Reg && MCI.getOperand(1).isImm() &&
|
||||
isShiftedUInt<5, 2>(MCI.getOperand(1).getImm())) {
|
||||
Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {
|
||||
return HexagonII::HSIG_S2;
|
||||
}
|
||||
// memw(Rs+#u4:2) = Rt
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
|
||||
MCI.getOperand(1).isImm() &&
|
||||
isShiftedUInt<4, 2>(MCI.getOperand(1).getImm())) {
|
||||
inRange<4, 2>(MCI, 1)) {
|
||||
return HexagonII::HSIG_S1;
|
||||
}
|
||||
break;
|
||||
@ -344,7 +338,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
Src2Reg = MCI.getOperand(2).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
|
||||
MCI.getOperand(1).isImm() && isUInt<4>(MCI.getOperand(1).getImm())) {
|
||||
inRange<4>(MCI, 1)) {
|
||||
return HexagonII::HSIG_S1;
|
||||
}
|
||||
break;
|
||||
@ -363,8 +357,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
Src2Reg = MCI.getOperand(2).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
|
||||
MCI.getOperand(1).isImm() &&
|
||||
isShiftedUInt<3, 1>(MCI.getOperand(1).getImm())) {
|
||||
inRange<3, 1>(MCI, 1)) {
|
||||
return HexagonII::HSIG_S2;
|
||||
}
|
||||
break;
|
||||
@ -374,8 +367,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
Src2Reg = MCI.getOperand(2).getReg();
|
||||
if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
|
||||
HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&
|
||||
MCI.getOperand(1).isImm() &&
|
||||
isShiftedInt<6, 3>(MCI.getOperand(1).getImm())) {
|
||||
inSRange<6, 3>(MCI, 1)) {
|
||||
return HexagonII::HSIG_S2;
|
||||
}
|
||||
break;
|
||||
@ -383,9 +375,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
// memw(Rs+#u4:2) = #U1
|
||||
Src1Reg = MCI.getOperand(0).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
|
||||
MCI.getOperand(1).isImm() &&
|
||||
isShiftedUInt<4, 2>(MCI.getOperand(1).getImm()) &&
|
||||
MCI.getOperand(2).isImm() && isUInt<1>(MCI.getOperand(2).getImm())) {
|
||||
inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {
|
||||
return HexagonII::HSIG_S2;
|
||||
}
|
||||
break;
|
||||
@ -393,16 +383,13 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
// memb(Rs+#u4) = #U1
|
||||
Src1Reg = MCI.getOperand(0).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
|
||||
MCI.getOperand(1).isImm() && isUInt<4>(MCI.getOperand(1).getImm()) &&
|
||||
MCI.getOperand(2).isImm() && isUInt<1>(MCI.getOperand(2).getImm())) {
|
||||
inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {
|
||||
return HexagonII::HSIG_S2;
|
||||
}
|
||||
break;
|
||||
case Hexagon::S2_allocframe:
|
||||
if (MCI.getOperand(0).isImm() &&
|
||||
isShiftedUInt<5, 3>(MCI.getOperand(0).getImm())) {
|
||||
if (inRange<5, 3>(MCI, 0))
|
||||
return HexagonII::HSIG_S2;
|
||||
}
|
||||
break;
|
||||
//
|
||||
// Group A:
|
||||
@ -428,8 +415,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
|
||||
// Rd = add(r29,#u6:2)
|
||||
if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
|
||||
MCI.getOperand(2).isImm() &&
|
||||
isShiftedUInt<6, 2>(MCI.getOperand(2).getImm())) {
|
||||
inRange<6, 2>(MCI, 2)) {
|
||||
return HexagonII::HSIG_A;
|
||||
}
|
||||
// Rx = add(Rx,#s7)
|
||||
@ -439,8 +425,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
// Rd = add(Rs,#1)
|
||||
// Rd = add(Rs,#-1)
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
MCI.getOperand(2).isImm() && ((MCI.getOperand(2).getImm() == 1) ||
|
||||
(MCI.getOperand(2).getImm() == -1))) {
|
||||
(minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {
|
||||
return HexagonII::HSIG_A;
|
||||
}
|
||||
}
|
||||
@ -460,8 +445,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
SrcReg = MCI.getOperand(1).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
MCI.getOperand(2).isImm() && ((MCI.getOperand(2).getImm() == 1) ||
|
||||
(MCI.getOperand(2).getImm() == 255))) {
|
||||
(minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {
|
||||
return HexagonII::HSIG_A;
|
||||
}
|
||||
break;
|
||||
@ -491,8 +475,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
DstReg = MCI.getOperand(0).getReg(); // Rd
|
||||
PredReg = MCI.getOperand(1).getReg(); // P0
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
|
||||
Hexagon::P0 == PredReg && MCI.getOperand(2).isImm() &&
|
||||
MCI.getOperand(2).getImm() == 0) {
|
||||
Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {
|
||||
return HexagonII::HSIG_A;
|
||||
}
|
||||
break;
|
||||
@ -502,7 +485,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
SrcReg = MCI.getOperand(1).getReg();
|
||||
if (Hexagon::P0 == DstReg &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
MCI.getOperand(2).isImm() && isUInt<2>(MCI.getOperand(2).getImm())) {
|
||||
inRange<2>(MCI, 2)) {
|
||||
return HexagonII::HSIG_A;
|
||||
}
|
||||
break;
|
||||
@ -511,10 +494,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
// Rdd = combine(#u2,#U2)
|
||||
DstReg = MCI.getOperand(0).getReg();
|
||||
if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
|
||||
// TODO: Handle Globals/Symbols
|
||||
(MCI.getOperand(1).isImm() && isUInt<2>(MCI.getOperand(1).getImm())) &&
|
||||
((MCI.getOperand(2).isImm() &&
|
||||
isUInt<2>(MCI.getOperand(2).getImm())))) {
|
||||
inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {
|
||||
return HexagonII::HSIG_A;
|
||||
}
|
||||
break;
|
||||
@ -524,7 +504,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
SrcReg = MCI.getOperand(1).getReg();
|
||||
if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
(MCI.getOperand(2).isImm() && MCI.getOperand(2).getImm() == 0)) {
|
||||
minConstant(MCI, 2) == 0) {
|
||||
return HexagonII::HSIG_A;
|
||||
}
|
||||
break;
|
||||
@ -534,7 +514,7 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
SrcReg = MCI.getOperand(2).getReg();
|
||||
if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
(MCI.getOperand(1).isImm() && MCI.getOperand(1).getImm() == 0)) {
|
||||
minConstant(MCI, 1) == 0) {
|
||||
return HexagonII::HSIG_A;
|
||||
}
|
||||
break;
|
||||
@ -556,19 +536,17 @@ unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
|
||||
|
||||
unsigned DstReg, SrcReg;
|
||||
|
||||
switch (potentialDuplex.getOpcode()) {
|
||||
case Hexagon::A2_addi:
|
||||
// testing for case of: Rx = add(Rx,#s7)
|
||||
DstReg = potentialDuplex.getOperand(0).getReg();
|
||||
SrcReg = potentialDuplex.getOperand(1).getReg();
|
||||
if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
|
||||
if (potentialDuplex.getOperand(2).isExpr())
|
||||
int64_t Value;
|
||||
if (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))
|
||||
return true;
|
||||
if (potentialDuplex.getOperand(2).isImm() &&
|
||||
!(isShiftedInt<7, 0>(potentialDuplex.getOperand(2).getImm())))
|
||||
if (!isShiftedInt<7, 0>(Value))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -576,15 +554,14 @@ bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
|
||||
DstReg = potentialDuplex.getOperand(0).getReg();
|
||||
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
|
||||
if (potentialDuplex.getOperand(1).isExpr())
|
||||
int64_t Value;
|
||||
if (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))
|
||||
return true;
|
||||
// Check for case of Rd = #-1.
|
||||
if (potentialDuplex.getOperand(1).isImm() &&
|
||||
(potentialDuplex.getOperand(1).getImm() == -1))
|
||||
if (Value == -1)
|
||||
return false;
|
||||
// Check for case of Rd = #u6.
|
||||
if (potentialDuplex.getOperand(1).isImm() &&
|
||||
!isShiftedUInt<6, 0>(potentialDuplex.getOperand(1).getImm()))
|
||||
if (!isShiftedUInt<6, 0>(Value))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -712,19 +689,23 @@ inline static void addOps(MCInst &subInstPtr, MCInst const &Inst,
|
||||
|
||||
MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
|
||||
MCInst Result;
|
||||
bool Absolute;
|
||||
int64_t Value;
|
||||
switch (Inst.getOpcode()) {
|
||||
default:
|
||||
// dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
|
||||
llvm_unreachable("Unimplemented subinstruction \n");
|
||||
break;
|
||||
case Hexagon::A2_addi:
|
||||
if (Inst.getOperand(2).isImm() && Inst.getOperand(2).getImm() == 1) {
|
||||
Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
|
||||
assert(Absolute);(void)Absolute;
|
||||
if (Value == 1) {
|
||||
Result.setOpcode(Hexagon::V4_SA1_inc);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 1);
|
||||
break;
|
||||
} // 1,2 SUBInst $Rd = add($Rs, #1)
|
||||
else if (Inst.getOperand(2).isImm() && Inst.getOperand(2).getImm() == -1) {
|
||||
else if (Value == -1) {
|
||||
Result.setOpcode(Hexagon::V4_SA1_dec);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 1);
|
||||
@ -754,7 +735,7 @@ MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
|
||||
addOps(Result, Inst, 0);
|
||||
break; // 1 SUBInst allocframe(#$u5_3)
|
||||
case Hexagon::A2_andir:
|
||||
if (Inst.getOperand(2).getImm() == 255) {
|
||||
if (minConstant(Inst, 2) == 255) {
|
||||
Result.setOpcode(Hexagon::V4_SA1_zxtb);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 1);
|
||||
@ -772,26 +753,27 @@ MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
|
||||
break; // 2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
|
||||
case Hexagon::A4_combineii:
|
||||
case Hexagon::A2_combineii:
|
||||
if (Inst.getOperand(1).getImm() == 1) {
|
||||
Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
|
||||
assert(Absolute);(void)Absolute;
|
||||
if (Value == 1) {
|
||||
Result.setOpcode(Hexagon::V4_SA1_combine1i);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 2);
|
||||
break; // 1,3 SUBInst $Rdd = combine(#1, #$u2)
|
||||
}
|
||||
|
||||
if (Inst.getOperand(1).getImm() == 3) {
|
||||
if (Value == 3) {
|
||||
Result.setOpcode(Hexagon::V4_SA1_combine3i);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 2);
|
||||
break; // 1,3 SUBInst $Rdd = combine(#3, #$u2)
|
||||
}
|
||||
if (Inst.getOperand(1).getImm() == 0) {
|
||||
if (Value == 0) {
|
||||
Result.setOpcode(Hexagon::V4_SA1_combine0i);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 2);
|
||||
break; // 1,3 SUBInst $Rdd = combine(#0, #$u2)
|
||||
}
|
||||
if (Inst.getOperand(1).getImm() == 2) {
|
||||
if (Value == 2) {
|
||||
Result.setOpcode(Hexagon::V4_SA1_combine2i);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 2);
|
||||
@ -894,12 +876,14 @@ MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
|
||||
break; // 1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)
|
||||
}
|
||||
case Hexagon::S4_storeirb_io:
|
||||
if (Inst.getOperand(2).getImm() == 0) {
|
||||
Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
|
||||
assert(Absolute);(void)Absolute;
|
||||
if (Value == 0) {
|
||||
Result.setOpcode(Hexagon::V4_SS2_storebi0);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 1);
|
||||
break; // 1,2 SUBInst memb($Rs + #$u4_0)=#0
|
||||
} else if (Inst.getOperand(2).getImm() == 1) {
|
||||
} else if (Value == 1) {
|
||||
Result.setOpcode(Hexagon::V4_SS2_storebi1);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 1);
|
||||
@ -923,12 +907,14 @@ MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
|
||||
addOps(Result, Inst, 2);
|
||||
break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
|
||||
case Hexagon::S4_storeiri_io:
|
||||
if (Inst.getOperand(2).getImm() == 0) {
|
||||
Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
|
||||
assert(Absolute);(void)Absolute;
|
||||
if (Value == 0) {
|
||||
Result.setOpcode(Hexagon::V4_SS2_storewi0);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 1);
|
||||
break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#0
|
||||
} else if (Inst.getOperand(2).getImm() == 1) {
|
||||
} else if (Value == 1) {
|
||||
Result.setOpcode(Hexagon::V4_SS2_storewi1);
|
||||
addOps(Result, Inst, 0);
|
||||
addOps(Result, Inst, 1);
|
||||
@ -983,7 +969,8 @@ MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
|
||||
addOps(Result, Inst, 0);
|
||||
break; // 2 SUBInst if (p0) $Rd = #0
|
||||
case Hexagon::A2_tfrsi:
|
||||
if (Inst.getOperand(1).isImm() && Inst.getOperand(1).getImm() == -1) {
|
||||
Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
|
||||
if (Absolute && Value == -1) {
|
||||
Result.setOpcode(Hexagon::V4_SA1_setin1);
|
||||
addOps(Result, Inst, 0);
|
||||
break; // 2 1 SUBInst $Rd = #-1
|
||||
@ -1044,6 +1031,8 @@ HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,
|
||||
<< "\n");
|
||||
bisReversable = false;
|
||||
}
|
||||
if (HexagonMCInstrInfo::isMemReorderDisabled(MCB)) // }:mem_noshuf
|
||||
bisReversable = false;
|
||||
|
||||
// Try in order.
|
||||
if (isOrderedDuplexPair(
|
||||
|
49
lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp
Normal file
49
lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
//===-- HexagonMCExpr.cpp - Hexagon specific MC expression classes
|
||||
//----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonMCExpr.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "hexagon-mcexpr"
|
||||
|
||||
HexagonNoExtendOperand *HexagonNoExtendOperand::Create(MCExpr const *Expr,
|
||||
MCContext &Ctx) {
|
||||
return new (Ctx) HexagonNoExtendOperand(Expr);
|
||||
}
|
||||
|
||||
bool HexagonNoExtendOperand::evaluateAsRelocatableImpl(
|
||||
MCValue &Res, MCAsmLayout const *Layout, MCFixup const *Fixup) const {
|
||||
return Expr->evaluateAsRelocatable(Res, Layout, Fixup);
|
||||
}
|
||||
|
||||
void HexagonNoExtendOperand::visitUsedExpr(MCStreamer &Streamer) const {}
|
||||
|
||||
MCFragment *llvm::HexagonNoExtendOperand::findAssociatedFragment() const {
|
||||
return Expr->findAssociatedFragment();
|
||||
}
|
||||
|
||||
void HexagonNoExtendOperand::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {}
|
||||
|
||||
MCExpr const *HexagonNoExtendOperand::getExpr() const { return Expr; }
|
||||
|
||||
bool HexagonNoExtendOperand::classof(MCExpr const *E) {
|
||||
return E->getKind() == MCExpr::Target;
|
||||
}
|
||||
|
||||
HexagonNoExtendOperand::HexagonNoExtendOperand(MCExpr const *Expr)
|
||||
: Expr(Expr) {}
|
||||
|
||||
void HexagonNoExtendOperand::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
|
||||
Expr->print(OS, MAI);
|
||||
}
|
35
lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h
Normal file
35
lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h
Normal file
@ -0,0 +1,35 @@
|
||||
//==- HexagonMCExpr.h - Hexagon specific MC expression classes --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONMCEXPR_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONMCEXPR_H
|
||||
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCInst;
|
||||
class HexagonNoExtendOperand : public MCTargetExpr {
|
||||
public:
|
||||
static HexagonNoExtendOperand *Create(MCExpr const *Expr, MCContext &Ctx);
|
||||
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
|
||||
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
|
||||
const MCFixup *Fixup) const override;
|
||||
void visitUsedExpr(MCStreamer &Streamer) const override;
|
||||
MCFragment *findAssociatedFragment() const override;
|
||||
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;
|
||||
static bool classof(MCExpr const *E);
|
||||
MCExpr const *getExpr() const;
|
||||
|
||||
private:
|
||||
HexagonNoExtendOperand(MCExpr const *Expr);
|
||||
MCExpr const *Expr;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONMCEXPR_H
|
@ -15,12 +15,32 @@
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonBaseInfo.h"
|
||||
#include "HexagonMCChecker.h"
|
||||
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,
|
||||
MCContext &Context) {
|
||||
MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context)));
|
||||
}
|
||||
|
||||
void HexagonMCInstrInfo::addConstExtender(MCInstrInfo const &MCII, MCInst &MCB,
|
||||
MCInst const &MCI) {
|
||||
assert(HexagonMCInstrInfo::isBundle(MCB));
|
||||
MCOperand const &exOp =
|
||||
MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
|
||||
|
||||
// Create the extender.
|
||||
MCInst *XMCI =
|
||||
new MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
|
||||
|
||||
MCB.addOperand(MCOperand::createInst(XMCI));
|
||||
}
|
||||
|
||||
iterator_range<MCInst::const_iterator>
|
||||
HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {
|
||||
assert(isBundle(MCI));
|
||||
@ -35,6 +55,38 @@ size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII,
|
||||
MCSubtargetInfo const &STI,
|
||||
MCContext &Context, MCInst &MCB,
|
||||
HexagonMCChecker *Check) {
|
||||
// Examine the packet and convert pairs of instructions to compound
|
||||
// instructions when possible.
|
||||
if (!HexagonDisableCompound)
|
||||
HexagonMCInstrInfo::tryCompound(MCII, Context, MCB);
|
||||
// Check the bundle for errors.
|
||||
bool CheckOk = Check ? Check->check() : true;
|
||||
if (!CheckOk)
|
||||
return false;
|
||||
HexagonMCShuffle(MCII, STI, MCB);
|
||||
// Examine the packet and convert pairs of instructions to duplex
|
||||
// instructions when possible.
|
||||
MCInst InstBundlePreDuplex = MCInst(MCB);
|
||||
if (!HexagonDisableDuplex) {
|
||||
SmallVector<DuplexCandidate, 8> possibleDuplexes;
|
||||
possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(MCII, MCB);
|
||||
HexagonMCShuffle(MCII, STI, Context, MCB, possibleDuplexes);
|
||||
}
|
||||
// Examines packet and pad the packet, if needed, when an
|
||||
// end-loop is in the bundle.
|
||||
HexagonMCInstrInfo::padEndloop(MCB);
|
||||
// If compounding and duplexing didn't reduce the size below
|
||||
// 4 or less we have a packet that is too big.
|
||||
if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE)
|
||||
return false;
|
||||
HexagonMCShuffle(MCII, STI, MCB);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HexagonMCInstrInfo::clampExtended(MCInstrInfo const &MCII, MCInst &MCI) {
|
||||
assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
|
||||
HexagonMCInstrInfo::isExtended(MCII, MCI));
|
||||
@ -64,6 +116,27 @@ MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass,
|
||||
return duplexInst;
|
||||
}
|
||||
|
||||
MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,
|
||||
MCInst const &Inst,
|
||||
MCOperand const &MO) {
|
||||
assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) ||
|
||||
HexagonMCInstrInfo::isExtended(MCII, Inst));
|
||||
|
||||
MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);
|
||||
MCInst XMI;
|
||||
XMI.setOpcode((Desc.isBranch() || Desc.isCall() ||
|
||||
HexagonMCInstrInfo::getType(MCII, Inst) == HexagonII::TypeCR)
|
||||
? Hexagon::A4_ext_b
|
||||
: Hexagon::A4_ext);
|
||||
if (MO.isImm())
|
||||
XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
|
||||
else if (MO.isExpr())
|
||||
XMI.addOperand(MCOperand::createExpr(MO.getExpr()));
|
||||
else
|
||||
llvm_unreachable("invalid extendable operand");
|
||||
return XMI;
|
||||
}
|
||||
|
||||
MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB,
|
||||
size_t Index) {
|
||||
assert(Index <= bundleSize(MCB));
|
||||
@ -76,6 +149,12 @@ MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void HexagonMCInstrInfo::extendIfNeeded(MCInstrInfo const &MCII, MCInst &MCB,
|
||||
MCInst const &MCI, bool MustExtend) {
|
||||
if (isConstExtended(MCII, MCI) || MustExtend)
|
||||
addConstExtender(MCII, MCB, MCI);
|
||||
}
|
||||
|
||||
HexagonII::MemAccessSize
|
||||
HexagonMCInstrInfo::getAccessSize(MCInstrInfo const &MCII, MCInst const &MCI) {
|
||||
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
|
||||
@ -186,6 +265,25 @@ MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII,
|
||||
return (MCO);
|
||||
}
|
||||
|
||||
/// Return the new value or the newly produced value.
|
||||
unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
|
||||
return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2);
|
||||
}
|
||||
|
||||
MCOperand const &
|
||||
HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
|
||||
MCOperand const &MCO = MCI.getOperand(O);
|
||||
|
||||
assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
|
||||
HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) &&
|
||||
MCO.isReg());
|
||||
return (MCO);
|
||||
}
|
||||
|
||||
int HexagonMCInstrInfo::getSubTarget(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
|
||||
@ -242,6 +340,13 @@ bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII,
|
||||
return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
|
||||
}
|
||||
|
||||
/// Return whether the insn produces a second value.
|
||||
bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
|
||||
return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2);
|
||||
}
|
||||
|
||||
MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {
|
||||
assert(isBundle(MCB));
|
||||
assert(Index < HEXAGON_PACKET_SIZE);
|
||||
@ -261,6 +366,11 @@ bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
|
||||
HexagonMCInstrInfo::getType(MCII, MCI) != HexagonII::TypeENDLOOP);
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
return (getType(MCII, MCI) == HexagonII::TypeCOMPOUND);
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) {
|
||||
return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
|
||||
(Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
|
||||
@ -282,14 +392,21 @@ bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
if (HexagonMCInstrInfo::isExtended(MCII, MCI))
|
||||
return true;
|
||||
|
||||
if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
|
||||
// Branch insns are handled as necessary by relaxation.
|
||||
if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||
|
||||
(HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCOMPOUND &&
|
||||
HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) ||
|
||||
(HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV &&
|
||||
HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()))
|
||||
return false;
|
||||
// Otherwise loop instructions and other CR insts are handled by relaxation
|
||||
else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) &&
|
||||
(MCI.getOpcode() != Hexagon::C4_addipc))
|
||||
return false;
|
||||
else if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
|
||||
return false;
|
||||
|
||||
short ExtOpNum = HexagonMCInstrInfo::getCExtOpNum(MCII, MCI);
|
||||
int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
|
||||
int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
|
||||
MCOperand const &MO = MCI.getOperand(ExtOpNum);
|
||||
MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI);
|
||||
|
||||
// We could be using an instruction with an extendable immediate and shoehorn
|
||||
// a global address into it. If it is a global address it will be constant
|
||||
@ -297,15 +414,13 @@ bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII,
|
||||
// We currently only handle isGlobal() because it is the only kind of
|
||||
// object we are going to end up with here for now.
|
||||
// In the future we probably should add isSymbol(), etc.
|
||||
if (MO.isExpr())
|
||||
assert(!MO.isImm());
|
||||
int64_t Value;
|
||||
if (!MO.getExpr()->evaluateAsAbsolute(Value))
|
||||
return true;
|
||||
|
||||
// If the extendable operand is not 'Immediate' type, the instruction should
|
||||
// have 'isExtended' flag set.
|
||||
assert(MO.isImm() && "Extendable operand must be Immediate type");
|
||||
|
||||
int ImmValue = MO.getImm();
|
||||
return (ImmValue < MinValue || ImmValue > MaxValue);
|
||||
int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
|
||||
int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
|
||||
return (MinValue > Value || Value > MaxValue);
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII,
|
||||
@ -374,6 +489,19 @@ bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII,
|
||||
return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
|
||||
return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask);
|
||||
}
|
||||
|
||||
/// Return whether the insn is newly predicated.
|
||||
bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
|
||||
return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI) {
|
||||
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
|
||||
@ -394,6 +522,18 @@ bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) {
|
||||
return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {
|
||||
assert(isBundle(MCI));
|
||||
auto Flags = MCI.getOperand(0).getImm();
|
||||
return (Flags & memReorderDisabledMask) != 0;
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isMemStoreReorderEnabled(MCInst const &MCI) {
|
||||
assert(isBundle(MCI));
|
||||
auto Flags = MCI.getOperand(0).getImm();
|
||||
return (Flags & memStoreReorderEnabledMask) != 0;
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {
|
||||
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
|
||||
return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask);
|
||||
@ -405,6 +545,27 @@ bool HexagonMCInstrInfo::isSoloAin1(MCInstrInfo const &MCII,
|
||||
return ((F >> HexagonII::SoloAin1Pos) & HexagonII::SoloAin1Mask);
|
||||
}
|
||||
|
||||
bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) {
|
||||
if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) &&
|
||||
(getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {
|
||||
auto Sentinal = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
|
||||
<< 8;
|
||||
if (MCI.size() <= Index)
|
||||
return Sentinal;
|
||||
MCOperand const &MCO = MCI.getOperand(Index);
|
||||
if (!MCO.isExpr())
|
||||
return Sentinal;
|
||||
int64_t Value;
|
||||
if (!MCO.getExpr()->evaluateAsAbsolute(Value))
|
||||
return Sentinal;
|
||||
return Value;
|
||||
}
|
||||
|
||||
void HexagonMCInstrInfo::padEndloop(MCInst &MCB) {
|
||||
MCInst Nop;
|
||||
Nop.setOpcode(Hexagon::A2_nop);
|
||||
@ -456,6 +617,20 @@ void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) {
|
||||
Operand.setImm(Operand.getImm() | innerLoopMask);
|
||||
}
|
||||
|
||||
void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) {
|
||||
assert(isBundle(MCI));
|
||||
MCOperand &Operand = MCI.getOperand(0);
|
||||
Operand.setImm(Operand.getImm() | memReorderDisabledMask);
|
||||
assert(isMemReorderDisabled(MCI));
|
||||
}
|
||||
|
||||
void HexagonMCInstrInfo::setMemStoreReorderEnabled(MCInst &MCI) {
|
||||
assert(isBundle(MCI));
|
||||
MCOperand &Operand = MCI.getOperand(0);
|
||||
Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask);
|
||||
assert(isMemStoreReorderEnabled(MCI));
|
||||
}
|
||||
|
||||
void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
|
||||
assert(isBundle(MCI));
|
||||
MCOperand &Operand = MCI.getOperand(0);
|
||||
|
@ -14,9 +14,11 @@
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
|
||||
|
||||
#include "HexagonMCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
|
||||
namespace llvm {
|
||||
class HexagonMCChecker;
|
||||
class MCContext;
|
||||
class MCInstrDesc;
|
||||
class MCInstrInfo;
|
||||
@ -39,20 +41,44 @@ int64_t const innerLoopMask = 1 << innerLoopOffset;
|
||||
size_t const outerLoopOffset = 1;
|
||||
int64_t const outerLoopMask = 1 << outerLoopOffset;
|
||||
|
||||
// do not reorder memory load/stores by default load/stores are re-ordered
|
||||
// and by default loads can be re-ordered
|
||||
size_t const memReorderDisabledOffset = 2;
|
||||
int64_t const memReorderDisabledMask = 1 << memReorderDisabledOffset;
|
||||
|
||||
// allow re-ordering of memory stores by default stores cannot be re-ordered
|
||||
size_t const memStoreReorderEnabledOffset = 3;
|
||||
int64_t const memStoreReorderEnabledMask = 1 << memStoreReorderEnabledOffset;
|
||||
|
||||
size_t const bundleInstructionsOffset = 1;
|
||||
|
||||
void addConstant(MCInst &MI, uint64_t Value, MCContext &Context);
|
||||
void addConstExtender(MCInstrInfo const &MCII, MCInst &MCB, MCInst const &MCI);
|
||||
|
||||
// Returns a iterator range of instructions in this bundle
|
||||
iterator_range<MCInst::const_iterator> bundleInstructions(MCInst const &MCI);
|
||||
|
||||
// Returns the number of instructions in the bundle
|
||||
size_t bundleSize(MCInst const &MCI);
|
||||
|
||||
// Put the packet in to canonical form, compound, duplex, pad, and shuffle
|
||||
bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
|
||||
MCContext &Context, MCInst &MCB,
|
||||
HexagonMCChecker *Checker);
|
||||
|
||||
// Clamp off upper 26 bits of extendable operand for emission
|
||||
void clampExtended(MCInstrInfo const &MCII, MCInst &MCI);
|
||||
|
||||
// Return the extender for instruction at Index or nullptr if none
|
||||
MCInst const *extenderForIndex(MCInst const &MCB, size_t Index);
|
||||
void extendIfNeeded(MCInstrInfo const &MCII, MCInst &MCB, MCInst const &MCI,
|
||||
bool MustExtend);
|
||||
|
||||
// Create a duplex instruction given the two subinsts
|
||||
MCInst *deriveDuplex(MCContext &Context, unsigned iClass, MCInst const &inst0,
|
||||
MCInst const &inst1);
|
||||
MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst,
|
||||
MCOperand const &MO);
|
||||
|
||||
// Convert this instruction in to a duplex subinst
|
||||
MCInst deriveSubInst(MCInst const &Inst);
|
||||
@ -108,6 +134,9 @@ unsigned short getNewValueOp(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
|
||||
// Return the operand that consumes or produces a new value.
|
||||
MCOperand const &getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
unsigned short getNewValueOp2(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
MCOperand const &getNewValueOperand2(MCInstrInfo const &MCII,
|
||||
MCInst const &MCI);
|
||||
|
||||
int getSubTarget(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
|
||||
@ -125,6 +154,7 @@ bool hasImmExt(MCInst const &MCI);
|
||||
|
||||
// Return whether the instruction is a legal new-value producer.
|
||||
bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
|
||||
// Return the instruction at Index
|
||||
MCInst const &instruction(MCInst const &MCB, size_t Index);
|
||||
@ -134,10 +164,24 @@ bool isBundle(MCInst const &MCI);
|
||||
|
||||
// Return whether the insn is an actual insn.
|
||||
bool isCanon(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
bool isCompound(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
|
||||
// Return the duplex iclass given the two duplex classes
|
||||
unsigned iClassOfDuplexPair(unsigned Ga, unsigned Gb);
|
||||
|
||||
int64_t minConstant(MCInst const &MCI, size_t Index);
|
||||
template <unsigned N, unsigned S>
|
||||
bool inRange(MCInst const &MCI, size_t Index) {
|
||||
return isShiftedUInt<N, S>(minConstant(MCI, Index));
|
||||
}
|
||||
template <unsigned N, unsigned S>
|
||||
bool inSRange(MCInst const &MCI, size_t Index) {
|
||||
return isShiftedInt<N, S>(minConstant(MCI, Index));
|
||||
}
|
||||
template <unsigned N> bool inRange(MCInst const &MCI, size_t Index) {
|
||||
return isUInt<N>(minConstant(MCI, Index));
|
||||
}
|
||||
|
||||
// Return whether the instruction needs to be constant extended.
|
||||
bool isConstExtended(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
|
||||
@ -173,6 +217,8 @@ bool isIntReg(unsigned Reg);
|
||||
|
||||
// Is this register suitable for use in a duplex subinst
|
||||
bool isIntRegForSubInst(unsigned Reg);
|
||||
bool isMemReorderDisabled(MCInst const &MCI);
|
||||
bool isMemStoreReorderEnabled(MCInst const &MCI);
|
||||
|
||||
// Return whether the insn is a new-value consumer.
|
||||
bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
@ -191,6 +237,8 @@ bool isOuterLoop(MCInst const &MCI);
|
||||
|
||||
// Return whether this instruction is predicated
|
||||
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
bool isPredicateLate(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
bool isPredicatedNew(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
|
||||
// Return whether the predicate sense is true
|
||||
bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
@ -209,6 +257,7 @@ bool isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
|
||||
/// Return whether the insn can be packaged only with an A-type insn in slot #1.
|
||||
bool isSoloAin1(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
bool isVector(MCInstrInfo const &MCII, MCInst const &MCI);
|
||||
|
||||
// Pad the bundle with nops to satisfy endloop requirements
|
||||
void padEndloop(MCInst &MCI);
|
||||
@ -220,6 +269,8 @@ void replaceDuplex(MCContext &Context, MCInst &MCB, DuplexCandidate Candidate);
|
||||
|
||||
// Marks a bundle as endloop0
|
||||
void setInnerLoop(MCInst &MCI);
|
||||
void setMemReorderDisabled(MCInst &MCI);
|
||||
void setMemStoreReorderEnabled(MCInst &MCI);
|
||||
|
||||
// Marks a bundle as endloop1
|
||||
void setOuterLoop(MCInst &MCI);
|
||||
|
@ -40,6 +40,14 @@ using namespace llvm;
|
||||
#define GET_REGINFO_MC_DESC
|
||||
#include "HexagonGenRegisterInfo.inc"
|
||||
|
||||
cl::opt<bool> llvm::HexagonDisableCompound
|
||||
("mno-compound",
|
||||
cl::desc("Disable looking for compound instructions for Hexagon"));
|
||||
|
||||
cl::opt<bool> llvm::HexagonDisableDuplex
|
||||
("mno-pairing",
|
||||
cl::desc("Disable looking for duplex instructions for Hexagon"));
|
||||
|
||||
MCInstrInfo *llvm::createHexagonMCInstrInfo() {
|
||||
MCInstrInfo *X = new MCInstrInfo();
|
||||
InitHexagonMCInstrInfo(X);
|
||||
@ -54,7 +62,10 @@ static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
|
||||
|
||||
static MCSubtargetInfo *
|
||||
createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
|
||||
return createHexagonMCSubtargetInfoImpl(TT, CPU, FS);
|
||||
StringRef CPUName = CPU;
|
||||
if (CPU.empty())
|
||||
CPUName = "hexagonv5";
|
||||
return createHexagonMCSubtargetInfoImpl(TT, CPUName, FS);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
namespace llvm {
|
||||
struct InstrItinerary;
|
||||
struct InstrStage;
|
||||
@ -33,7 +35,8 @@ class raw_ostream;
|
||||
class raw_pwrite_stream;
|
||||
|
||||
extern Target TheHexagonTarget;
|
||||
|
||||
extern cl::opt<bool> HexagonDisableCompound;
|
||||
extern cl::opt<bool> HexagonDisableDuplex;
|
||||
extern const InstrStage HexagonStages[];
|
||||
|
||||
MCInstrInfo *createHexagonMCInstrInfo();
|
||||
|
@ -108,6 +108,8 @@ public:
|
||||
SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns.
|
||||
SHUFFLE_ERROR_NOSLOTS, ///< No free slots for other insns.
|
||||
SHUFFLE_ERROR_SLOTS, ///< Over-subscribed slots.
|
||||
SHUFFLE_ERROR_ERRATA2, ///< Errata violation (v60).
|
||||
SHUFFLE_ERROR_STORE_LOAD_CONFLICT, ///< store/load conflict
|
||||
SHUFFLE_ERROR_UNKNOWN ///< Unknown error.
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
; RUN: llc -march=hexagon -hexagon-small-data-threshold=0 < %s | FileCheck %s
|
||||
; Check that we generate load instructions with absolute addressing mode.
|
||||
; XFAIL: *
|
||||
|
||||
@a0 = external global i32
|
||||
@a1 = external global i32
|
||||
|
@ -1,6 +1,7 @@
|
||||
; RUN: llc -march=hexagon < %s | FileCheck %s
|
||||
; Check that we generate absolute addressing mode instructions
|
||||
; with immediate value.
|
||||
; XFAIL: *
|
||||
|
||||
define i32 @f1(i32 %i) nounwind {
|
||||
; CHECK: memw(##786432){{ *}}={{ *}}r{{[0-9]+}}
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -march=hexagon < %s | FileCheck %s
|
||||
; XFAIL: *
|
||||
|
||||
; Check that we don't generate an invalid packet with too many instructions
|
||||
; due to a store that has a must-extend operand.
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -march=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
; XFAIL: *
|
||||
|
||||
; CHECK: p0 = cmp.gt(r0,#-1); if (!p0.new) jump:nt
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv4 -disable-dfa-sched -disable-hexagon-misched < %s | FileCheck %s
|
||||
; XFAIL: *
|
||||
|
||||
@num = external global i32
|
||||
@acc = external global i32
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
|
||||
; XFAIL: *
|
||||
|
||||
; CHECK: r{{[0-9]+}} = ##i129_l+16
|
||||
; CHECK: r{{[0-9]+}} = ##i129_s+16
|
||||
|
4
test/MC/Disassembler/Hexagon/invalid_packet.txt
Normal file
4
test/MC/Disassembler/Hexagon/invalid_packet.txt
Normal file
@ -0,0 +1,4 @@
|
||||
# RUN: llvm-mc -triple=hexagon -disassemble < %s 2>&1 | FileCheck %s
|
||||
|
||||
#CHECK: warning: invalid instruction encoding
|
||||
0x00 0x40 0x20 0x6c 0x00 0xc0 0x00 0x7f
|
@ -11,149 +11,149 @@
|
||||
|
||||
# Compare and jump
|
||||
0x00 0xc0 0x89 0x11
|
||||
# CHECK: p0 = cmp.eq(r9,#-1); if (p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.eq(r17,#-1); if (p0.new) jump:nt
|
||||
0x00 0xc1 0x89 0x11
|
||||
# CHECK: p0 = cmp.gt(r9,#-1); if (p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gt(r17,#-1); if (p0.new) jump:nt
|
||||
0x00 0xc3 0x89 0x11
|
||||
# CHECK: p0 = tstbit(r9, #0); if (p0.new) jump:nt
|
||||
# CHECK: p0 = tstbit(r17, #0); if (p0.new) jump:nt
|
||||
0x00 0xe0 0x89 0x11
|
||||
# CHECK: p0 = cmp.eq(r9,#-1); if (p0.new) jump:t
|
||||
# CHECK: p0 = cmp.eq(r17,#-1); if (p0.new) jump:t
|
||||
0x00 0xe1 0x89 0x11
|
||||
# CHECK: p0 = cmp.gt(r9,#-1); if (p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gt(r17,#-1); if (p0.new) jump:t
|
||||
0x00 0xe3 0x89 0x11
|
||||
# CHECK: p0 = tstbit(r9, #0); if (p0.new) jump:t
|
||||
# CHECK: p0 = tstbit(r17, #0); if (p0.new) jump:t
|
||||
0x00 0xc0 0xc9 0x11
|
||||
# CHECK: p0 = cmp.eq(r9,#-1); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.eq(r17,#-1); if (!p0.new) jump:nt
|
||||
0x00 0xc1 0xc9 0x11
|
||||
# CHECK: p0 = cmp.gt(r9,#-1); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gt(r17,#-1); if (!p0.new) jump:nt
|
||||
0x00 0xc3 0xc9 0x11
|
||||
# CHECK: p0 = tstbit(r9, #0); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = tstbit(r17, #0); if (!p0.new) jump:nt
|
||||
0x00 0xe0 0xc9 0x11
|
||||
# CHECK: p0 = cmp.eq(r9,#-1); if (!p0.new) jump:t
|
||||
# CHECK: p0 = cmp.eq(r17,#-1); if (!p0.new) jump:t
|
||||
0x00 0xe1 0xc9 0x11
|
||||
# CHECK: p0 = cmp.gt(r9,#-1); if (!p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gt(r17,#-1); if (!p0.new) jump:t
|
||||
0x00 0xe3 0xc9 0x11
|
||||
# CHECK: p0 = tstbit(r9, #0); if (!p0.new) jump:t
|
||||
# CHECK: p0 = tstbit(r17, #0); if (!p0.new) jump:t
|
||||
0x00 0xd5 0x09 0x10
|
||||
# CHECK: p0 = cmp.eq(r9, #21); if (p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.eq(r17, #21); if (p0.new) jump:nt
|
||||
0x00 0xf5 0x09 0x10
|
||||
# CHECK: p0 = cmp.eq(r9, #21); if (p0.new) jump:t
|
||||
# CHECK: p0 = cmp.eq(r17, #21); if (p0.new) jump:t
|
||||
0x00 0xd5 0x49 0x10
|
||||
# CHECK: p0 = cmp.eq(r9, #21); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.eq(r17, #21); if (!p0.new) jump:nt
|
||||
0x00 0xf5 0x49 0x10
|
||||
# CHECK: p0 = cmp.eq(r9, #21); if (!p0.new) jump:t
|
||||
# CHECK: p0 = cmp.eq(r17, #21); if (!p0.new) jump:t
|
||||
0x00 0xd5 0x89 0x10
|
||||
# CHECK: p0 = cmp.gt(r9, #21); if (p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gt(r17, #21); if (p0.new) jump:nt
|
||||
0x00 0xf5 0x89 0x10
|
||||
# CHECK: p0 = cmp.gt(r9, #21); if (p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gt(r17, #21); if (p0.new) jump:t
|
||||
0x00 0xd5 0xc9 0x10
|
||||
# CHECK: p0 = cmp.gt(r9, #21); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gt(r17, #21); if (!p0.new) jump:nt
|
||||
0x00 0xf5 0xc9 0x10
|
||||
# CHECK: p0 = cmp.gt(r9, #21); if (!p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gt(r17, #21); if (!p0.new) jump:t
|
||||
0x00 0xd5 0x09 0x11
|
||||
# CHECK: p0 = cmp.gtu(r9, #21); if (p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gtu(r17, #21); if (p0.new) jump:nt
|
||||
0x00 0xf5 0x09 0x11
|
||||
# CHECK: p0 = cmp.gtu(r9, #21); if (p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gtu(r17, #21); if (p0.new) jump:t
|
||||
0x00 0xd5 0x49 0x11
|
||||
# CHECK: p0 = cmp.gtu(r9, #21); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gtu(r17, #21); if (!p0.new) jump:nt
|
||||
0x00 0xf5 0x49 0x11
|
||||
# CHECK: p0 = cmp.gtu(r9, #21); if (!p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gtu(r17, #21); if (!p0.new) jump:t
|
||||
0x00 0xc0 0x89 0x13
|
||||
# CHECK: p1 = cmp.eq(r9,#-1); if (p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.eq(r17,#-1); if (p1.new) jump:nt
|
||||
0x00 0xc1 0x89 0x13
|
||||
# CHECK: p1 = cmp.gt(r9,#-1); if (p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gt(r17,#-1); if (p1.new) jump:nt
|
||||
0x00 0xc3 0x89 0x13
|
||||
# CHECK: p1 = tstbit(r9, #0); if (p1.new) jump:nt
|
||||
# CHECK: p1 = tstbit(r17, #0); if (p1.new) jump:nt
|
||||
0x00 0xe0 0x89 0x13
|
||||
# CHECK: p1 = cmp.eq(r9,#-1); if (p1.new) jump:t
|
||||
# CHECK: p1 = cmp.eq(r17,#-1); if (p1.new) jump:t
|
||||
0x00 0xe1 0x89 0x13
|
||||
# CHECK: p1 = cmp.gt(r9,#-1); if (p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gt(r17,#-1); if (p1.new) jump:t
|
||||
0x00 0xe3 0x89 0x13
|
||||
# CHECK: p1 = tstbit(r9, #0); if (p1.new) jump:t
|
||||
# CHECK: p1 = tstbit(r17, #0); if (p1.new) jump:t
|
||||
0x00 0xc0 0xc9 0x13
|
||||
# CHECK: p1 = cmp.eq(r9,#-1); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.eq(r17,#-1); if (!p1.new) jump:nt
|
||||
0x00 0xc1 0xc9 0x13
|
||||
# CHECK: p1 = cmp.gt(r9,#-1); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gt(r17,#-1); if (!p1.new) jump:nt
|
||||
0x00 0xc3 0xc9 0x13
|
||||
# CHECK: p1 = tstbit(r9, #0); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = tstbit(r17, #0); if (!p1.new) jump:nt
|
||||
0x00 0xe0 0xc9 0x13
|
||||
# CHECK: p1 = cmp.eq(r9,#-1); if (!p1.new) jump:t
|
||||
# CHECK: p1 = cmp.eq(r17,#-1); if (!p1.new) jump:t
|
||||
0x00 0xe1 0xc9 0x13
|
||||
# CHECK: p1 = cmp.gt(r9,#-1); if (!p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gt(r17,#-1); if (!p1.new) jump:t
|
||||
0x00 0xe3 0xc9 0x13
|
||||
# CHECK: p1 = tstbit(r9, #0); if (!p1.new) jump:t
|
||||
# CHECK: p1 = tstbit(r17, #0); if (!p1.new) jump:t
|
||||
0x00 0xd5 0x09 0x12
|
||||
# CHECK: p1 = cmp.eq(r9, #21); if (p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.eq(r17, #21); if (p1.new) jump:nt
|
||||
0x00 0xf5 0x09 0x12
|
||||
# CHECK: p1 = cmp.eq(r9, #21); if (p1.new) jump:t
|
||||
# CHECK: p1 = cmp.eq(r17, #21); if (p1.new) jump:t
|
||||
0x00 0xd5 0x49 0x12
|
||||
# CHECK: p1 = cmp.eq(r9, #21); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.eq(r17, #21); if (!p1.new) jump:nt
|
||||
0x00 0xf5 0x49 0x12
|
||||
# CHECK: p1 = cmp.eq(r9, #21); if (!p1.new) jump:t
|
||||
# CHECK: p1 = cmp.eq(r17, #21); if (!p1.new) jump:t
|
||||
0x00 0xd5 0x89 0x12
|
||||
# CHECK: p1 = cmp.gt(r9, #21); if (p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gt(r17, #21); if (p1.new) jump:nt
|
||||
0x00 0xf5 0x89 0x12
|
||||
# CHECK: p1 = cmp.gt(r9, #21); if (p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gt(r17, #21); if (p1.new) jump:t
|
||||
0x00 0xd5 0xc9 0x12
|
||||
# CHECK: p1 = cmp.gt(r9, #21); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gt(r17, #21); if (!p1.new) jump:nt
|
||||
0x00 0xf5 0xc9 0x12
|
||||
# CHECK: p1 = cmp.gt(r9, #21); if (!p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gt(r17, #21); if (!p1.new) jump:t
|
||||
0x00 0xd5 0x09 0x13
|
||||
# CHECK: p1 = cmp.gtu(r9, #21); if (p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gtu(r17, #21); if (p1.new) jump:nt
|
||||
0x00 0xf5 0x09 0x13
|
||||
# CHECK: p1 = cmp.gtu(r9, #21); if (p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gtu(r17, #21); if (p1.new) jump:t
|
||||
0x00 0xd5 0x49 0x13
|
||||
# CHECK: p1 = cmp.gtu(r9, #21); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gtu(r17, #21); if (!p1.new) jump:nt
|
||||
0x00 0xf5 0x49 0x13
|
||||
# CHECK: p1 = cmp.gtu(r9, #21); if (!p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gtu(r17, #21); if (!p1.new) jump:t
|
||||
0x00 0xcd 0x09 0x14
|
||||
# CHECK: p0 = cmp.eq(r9, r13); if (p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.eq(r17, r21); if (p0.new) jump:nt
|
||||
0x00 0xdd 0x09 0x14
|
||||
# CHECK: p1 = cmp.eq(r9, r13); if (p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.eq(r17, r21); if (p1.new) jump:nt
|
||||
0x00 0xed 0x09 0x14
|
||||
# CHECK: p0 = cmp.eq(r9, r13); if (p0.new) jump:t
|
||||
# CHECK: p0 = cmp.eq(r17, r21); if (p0.new) jump:t
|
||||
0x00 0xfd 0x09 0x14
|
||||
# CHECK: p1 = cmp.eq(r9, r13); if (p1.new) jump:t
|
||||
# CHECK: p1 = cmp.eq(r17, r21); if (p1.new) jump:t
|
||||
0x00 0xcd 0x49 0x14
|
||||
# CHECK: p0 = cmp.eq(r9, r13); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.eq(r17, r21); if (!p0.new) jump:nt
|
||||
0x00 0xdd 0x49 0x14
|
||||
# CHECK: p1 = cmp.eq(r9, r13); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.eq(r17, r21); if (!p1.new) jump:nt
|
||||
0x00 0xed 0x49 0x14
|
||||
# CHECK: p0 = cmp.eq(r9, r13); if (!p0.new) jump:t
|
||||
# CHECK: p0 = cmp.eq(r17, r21); if (!p0.new) jump:t
|
||||
0x00 0xfd 0x49 0x14
|
||||
# CHECK: p1 = cmp.eq(r9, r13); if (!p1.new) jump:t
|
||||
# CHECK: p1 = cmp.eq(r17, r21); if (!p1.new) jump:t
|
||||
0x00 0xcd 0x89 0x14
|
||||
# CHECK: p0 = cmp.gt(r9, r13); if (p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gt(r17, r21); if (p0.new) jump:nt
|
||||
0x00 0xdd 0x89 0x14
|
||||
# CHECK: p1 = cmp.gt(r9, r13); if (p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gt(r17, r21); if (p1.new) jump:nt
|
||||
0x00 0xed 0x89 0x14
|
||||
# CHECK: p0 = cmp.gt(r9, r13); if (p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gt(r17, r21); if (p0.new) jump:t
|
||||
0x00 0xfd 0x89 0x14
|
||||
# CHECK: p1 = cmp.gt(r9, r13); if (p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gt(r17, r21); if (p1.new) jump:t
|
||||
0x00 0xcd 0xc9 0x14
|
||||
# CHECK: p0 = cmp.gt(r9, r13); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gt(r17, r21); if (!p0.new) jump:nt
|
||||
0x00 0xdd 0xc9 0x14
|
||||
# CHECK: p1 = cmp.gt(r9, r13); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gt(r17, r21); if (!p1.new) jump:nt
|
||||
0x00 0xed 0xc9 0x14
|
||||
# CHECK: p0 = cmp.gt(r9, r13); if (!p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gt(r17, r21); if (!p0.new) jump:t
|
||||
0x00 0xfd 0xc9 0x14
|
||||
# CHECK: p1 = cmp.gt(r9, r13); if (!p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gt(r17, r21); if (!p1.new) jump:t
|
||||
0x00 0xcd 0x09 0x15
|
||||
# CHECK: p0 = cmp.gtu(r9, r13); if (p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gtu(r17, r21); if (p0.new) jump:nt
|
||||
0x00 0xdd 0x09 0x15
|
||||
# CHECK: p1 = cmp.gtu(r9, r13); if (p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gtu(r17, r21); if (p1.new) jump:nt
|
||||
0x00 0xed 0x09 0x15
|
||||
# CHECK: p0 = cmp.gtu(r9, r13); if (p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gtu(r17, r21); if (p0.new) jump:t
|
||||
0x00 0xfd 0x09 0x15
|
||||
# CHECK: p1 = cmp.gtu(r9, r13); if (p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gtu(r17, r21); if (p1.new) jump:t
|
||||
0x00 0xcd 0x49 0x15
|
||||
# CHECK: p0 = cmp.gtu(r9, r13); if (!p0.new) jump:nt
|
||||
# CHECK: p0 = cmp.gtu(r17, r21); if (!p0.new) jump:nt
|
||||
0x00 0xdd 0x49 0x15
|
||||
# CHECK: p1 = cmp.gtu(r9, r13); if (!p1.new) jump:nt
|
||||
# CHECK: p1 = cmp.gtu(r17, r21); if (!p1.new) jump:nt
|
||||
0x00 0xed 0x49 0x15
|
||||
# CHECK: p0 = cmp.gtu(r9, r13); if (!p0.new) jump:t
|
||||
# CHECK: p0 = cmp.gtu(r17, r21); if (!p0.new) jump:t
|
||||
0x00 0xfd 0x49 0x15
|
||||
# CHECK: p1 = cmp.gtu(r9, r13); if (!p1.new) jump:t
|
||||
# CHECK: p1 = cmp.gtu(r17, r21); if (!p1.new) jump:t
|
||||
|
||||
# Jump to address
|
||||
0x22 0xc0 0x00 0x58
|
||||
@ -197,6 +197,6 @@
|
||||
|
||||
# Transfer and jump
|
||||
0x00 0xd5 0x09 0x16
|
||||
# CHECK: r9 = #21 ; jump
|
||||
# CHECK: r17 = #21 ; jump
|
||||
0x00 0xc9 0x0d 0x17
|
||||
# CHECK: r9 = r13 ; jump
|
||||
# CHECK: r17 = r21 ; jump
|
||||
|
@ -1,15 +1,22 @@
|
||||
# RUN: llvm-mc -triple hexagon -disassemble < %s | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.5 LD
|
||||
# XFAIL: *
|
||||
|
||||
# Load doubleword
|
||||
0x90 0xff 0xd5 0x3a
|
||||
# CHECK: r17:16 = memd(r21 + r31<<#3)
|
||||
0x10 0xc5 0xc0 0x49
|
||||
# CHECK: r17:16 = memd(##320)
|
||||
0xb0 0xc2 0xc0 0x49
|
||||
# CHECK: r17:16 = memd(#168)
|
||||
0x02 0x40 0x00 0x00 0x10 0xc5 0xc0 0x49
|
||||
# CHECK: r17:16 = memd(##168)
|
||||
0xd0 0xc0 0xd5 0x91
|
||||
# CHECK: r17:16 = memd(r21 + #48)
|
||||
0xb0 0xe0 0xd5 0x99
|
||||
# CHECK: r17:16 = memd(r21 ++ #40:circ(m1))
|
||||
0x10 0xe2 0xd5 0x99
|
||||
# CHECK: r17:16 = memd(r21 ++ I:circ(m1))
|
||||
0x00 0x40 0x00 0x00 0x70 0xd7 0xd5 0x9b
|
||||
# CHECK: r17:16 = memd(r21 = ##31)
|
||||
0xb0 0xc0 0xd5 0x9b
|
||||
# CHECK: r17:16 = memd(r21++#40)
|
||||
0x10 0xe0 0xd5 0x9d
|
||||
@ -53,6 +60,8 @@
|
||||
0x91 0xff 0x15 0x3a
|
||||
# CHECK: r17 = memb(r21 + r31<<#3)
|
||||
0xb1 0xc2 0x00 0x49
|
||||
# CHECK: r17 = memb(#21)
|
||||
0x00 0x40 0x00 0x00 0xb1 0xc2 0x00 0x49
|
||||
# CHECK: r17 = memb(##21)
|
||||
0xf1 0xc3 0x15 0x91
|
||||
# CHECK: r17 = memb(r21 + #31)
|
||||
@ -60,6 +69,8 @@
|
||||
# CHECK: r17 = memb(r21 ++ #5:circ(m1))
|
||||
0x11 0xe2 0x15 0x99
|
||||
# CHECK: r17 = memb(r21 ++ I:circ(m1))
|
||||
0x00 0x40 0x00 0x00 0x71 0xd7 0x15 0x9b
|
||||
# CHECK: r17 = memb(r21 = ##31)
|
||||
0xb1 0xc0 0x15 0x9b
|
||||
# CHECK: r17 = memb(r21++#5)
|
||||
0x11 0xe0 0x15 0x9d
|
||||
@ -99,17 +110,37 @@
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) r17 = memb(r21++#5)
|
||||
|
||||
# Load byte into shifted vector
|
||||
0xf0 0xc3 0x95 0x90
|
||||
# CHECK: r17:16 = memb_fifo(r21 + #31)
|
||||
0xb0 0xe0 0x95 0x98
|
||||
# CHECK: r17:16 = memb_fifo(r21 ++ #5:circ(m1))
|
||||
0x10 0xe2 0x95 0x98
|
||||
# CHECK: r17:16 = memb_fifo(r21 ++ I:circ(m1))
|
||||
|
||||
# Load half into shifted vector
|
||||
0xf0 0xc3 0x55 0x90
|
||||
# CHECK: r17:16 = memh_fifo(r21 + #62)
|
||||
0xb0 0xe0 0x55 0x98
|
||||
# CHECK: r17:16 = memh_fifo(r21 ++ #10:circ(m1))
|
||||
0x10 0xe2 0x55 0x98
|
||||
# CHECK: r17:16 = memh_fifo(r21 ++ I:circ(m1))
|
||||
|
||||
# Load halfword
|
||||
0x91 0xff 0x55 0x3a
|
||||
# CHECK: r17 = memh(r21 + r31<<#3)
|
||||
0x51 0xc5 0x40 0x49
|
||||
# CHECK: r17 = memh(##84)
|
||||
0xb1 0xc2 0x40 0x49
|
||||
# CHECK: r17 = memh(#42)
|
||||
0x00 0x40 0x00 0x00 0x51 0xc5 0x40 0x49
|
||||
# CHECK: r17 = memh(##42)
|
||||
0xf1 0xc3 0x55 0x91
|
||||
# CHECK: r17 = memh(r21 + #62)
|
||||
0xb1 0xe0 0x55 0x99
|
||||
# CHECK: r17 = memh(r21 ++ #10:circ(m1))
|
||||
0x11 0xe2 0x55 0x99
|
||||
# CHECK: r17 = memh(r21 ++ I:circ(m1))
|
||||
0x00 0x40 0x00 0x00 0x71 0xd7 0x55 0x9b
|
||||
# CHECK: r17 = memh(r21 = ##31)
|
||||
0xb1 0xc0 0x55 0x9b
|
||||
# CHECK: r17 = memh(r21++#10)
|
||||
0x11 0xe0 0x55 0x9d
|
||||
@ -138,11 +169,23 @@
|
||||
0x03 0x40 0x45 0x85 0xb1 0xfe 0x55 0x9b
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) r17 = memh(r21++#10)
|
||||
0xf1 0xdb 0x55 0x41
|
||||
# CHECK: if (p3) r17 = memh(r21 + #62)
|
||||
0xf1 0xdb 0x55 0x45
|
||||
# CHECK: if (!p3) r17 = memh(r21 + #62)
|
||||
0x03 0x40 0x45 0x85 0xf1 0xdb 0x55 0x43
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (p3.new) r17 = memh(r21 + #62)
|
||||
0x03 0x40 0x45 0x85 0xf1 0xdb 0x55 0x47
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) r17 = memh(r21 + #62)
|
||||
|
||||
# Load unsigned byte
|
||||
0x91 0xff 0x35 0x3a
|
||||
# CHECK: r17 = memub(r21 + r31<<#3)
|
||||
0xb1 0xc2 0x20 0x49
|
||||
# CHECK: r17 = memub(#21)
|
||||
0x00 0x40 0x00 0x00 0xb1 0xc2 0x20 0x49
|
||||
# CHECK: r17 = memub(##21)
|
||||
0xf1 0xc3 0x35 0x91
|
||||
# CHECK: r17 = memub(r21 + #31)
|
||||
@ -150,6 +193,8 @@
|
||||
# CHECK: r17 = memub(r21 ++ #5:circ(m1))
|
||||
0x11 0xe2 0x35 0x99
|
||||
# CHECK: r17 = memub(r21 ++ I:circ(m1))
|
||||
0x00 0x40 0x00 0x00 0x71 0xd7 0x35 0x9b
|
||||
# CHECK: r17 = memub(r21 = ##31)
|
||||
0xb1 0xc0 0x35 0x9b
|
||||
# CHECK: r17 = memub(r21++#5)
|
||||
0x11 0xe0 0x35 0x9d
|
||||
@ -192,14 +237,18 @@
|
||||
# Load unsigned halfword
|
||||
0x91 0xff 0x75 0x3a
|
||||
# CHECK: r17 = memuh(r21 + r31<<#3)
|
||||
0x51 0xc5 0x60 0x49
|
||||
# CHECK: r17 = memuh(##84)
|
||||
0xb1 0xc2 0x60 0x49
|
||||
# CHECK: r17 = memuh(#42)
|
||||
0x00 0x40 0x00 0x00 0x51 0xc5 0x60 0x49
|
||||
# CHECK: r17 = memuh(##42)
|
||||
0xb1 0xc2 0x75 0x91
|
||||
# CHECK: r17 = memuh(r21 + #42)
|
||||
0xb1 0xe0 0x75 0x99
|
||||
# CHECK: r17 = memuh(r21 ++ #10:circ(m1))
|
||||
0x11 0xe2 0x75 0x99
|
||||
# CHECK: r17 = memuh(r21 ++ I:circ(m1))
|
||||
0x00 0x40 0x00 0x00 0x71 0xd7 0x75 0x9b
|
||||
# CHECK: r17 = memuh(r21 = ##31)
|
||||
0xb1 0xc0 0x75 0x9b
|
||||
# CHECK: r17 = memuh(r21++#10)
|
||||
0x11 0xe0 0x75 0x9d
|
||||
@ -242,14 +291,18 @@
|
||||
# Load word
|
||||
0x91 0xff 0x95 0x3a
|
||||
# CHECK: r17 = memw(r21 + r31<<#3)
|
||||
0x91 0xc2 0x80 0x49
|
||||
# CHECK: r17 = memw(##80)
|
||||
0xb1 0xc2 0x80 0x49
|
||||
# CHECK: r17 = memw(#84)
|
||||
0x01 0x40 0x00 0x00 0x91 0xc2 0x80 0x49
|
||||
# CHECK: r17 = memw(##84)
|
||||
0xb1 0xc2 0x95 0x91
|
||||
# CHECK: r17 = memw(r21 + #84)
|
||||
0xb1 0xe0 0x95 0x99
|
||||
# CHECK: r17 = memw(r21 ++ #20:circ(m1))
|
||||
0x11 0xe2 0x95 0x99
|
||||
# CHECK: r17 = memw(r21 ++ I:circ(m1))
|
||||
0x00 0x40 0x00 0x00 0x71 0xd7 0x95 0x9b
|
||||
# CHECK: r17 = memw(r21 = ##31)
|
||||
0xb1 0xc0 0x95 0x9b
|
||||
# CHECK: r17 = memw(r21++#20)
|
||||
0x11 0xe0 0x95 0x9d
|
||||
@ -338,14 +391,36 @@
|
||||
# CHECK: r17:16 = memubh(r21 ++ #20:circ(m1))
|
||||
0x10 0xe2 0xb5 0x98
|
||||
# CHECK: r17:16 = memubh(r21 ++ I:circ(m1))
|
||||
0x00 0x40 0x00 0x00 0x71 0xd7 0x35 0x9a
|
||||
# CHECK: r17 = membh(r21 = ##31)
|
||||
0xb1 0xc0 0x35 0x9a
|
||||
# CHECK: r17 = membh(r21++#10)
|
||||
0x00 0x40 0x00 0x00 0x71 0xd7 0x75 0x9a
|
||||
# CHECK: r17 = memubh(r21 = ##31)
|
||||
0xb1 0xc0 0x75 0x9a
|
||||
# CHECK: r17 = memubh(r21++#10)
|
||||
0x00 0x40 0x00 0x00 0x70 0xd7 0xb5 0x9a
|
||||
# CHECK: r17:16 = memubh(r21 = ##31)
|
||||
0xb0 0xc0 0xb5 0x9a
|
||||
# CHECK: r17:16 = memubh(r21++#20)
|
||||
0x00 0x40 0x00 0x00 0x70 0xd7 0xf5 0x9a
|
||||
# CHECK: r17:16 = membh(r21 = ##31)
|
||||
0xb0 0xc0 0xf5 0x9a
|
||||
# CHECK: r17:16 = membh(r21++#20)
|
||||
0x00 0x40 0x00 0x00 0xf1 0xf7 0x35 0x9c
|
||||
# CHECK: r17 = membh(r21<<#3 + ##31)
|
||||
0x11 0xe0 0x35 0x9c
|
||||
# CHECK: r17 = membh(r21++m1)
|
||||
0x00 0x40 0x00 0x00 0xf1 0xf7 0x75 0x9c
|
||||
# CHECK: r17 = memubh(r21<<#3 + ##31)
|
||||
0x11 0xe0 0x75 0x9c
|
||||
# CHECK: r17 = memubh(r21++m1)
|
||||
0x00 0x40 0x00 0x00 0xf0 0xf7 0xf5 0x9c
|
||||
# CHECK: r17:16 = membh(r21<<#3 + ##31)
|
||||
0x10 0xe0 0xf5 0x9c
|
||||
# CHECK: r17:16 = membh(r21++m1)
|
||||
0x00 0x40 0x00 0x00 0xf0 0xf7 0xb5 0x9c
|
||||
# CHECK: r17:16 = memubh(r21<<#3 + ##31)
|
||||
0x11 0xe0 0x35 0x9c
|
||||
# CHECK: r17 = membh(r21++m1)
|
||||
0x11 0xe0 0x75 0x9c
|
||||
|
@ -1,3 +1,3 @@
|
||||
if not 'Hexagon' in config.root.targets:
|
||||
config.unsupported = True
|
||||
|
||||
if not 'Hexagon' in config.root.targets:
|
||||
config.unsupported = True
|
||||
|
||||
|
@ -4,133 +4,133 @@
|
||||
# Jump to address conditioned on new register value
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x20
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.eq(r2.new, r21)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.eq(r17.new, r21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x20
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.eq(r2.new, r21)) jump:t
|
||||
# CHECK-NEXT: if (cmp.eq(r17.new, r21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x20
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.eq(r2.new, r21)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.eq(r17.new, r21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x20
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.eq(r2.new, r21)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.eq(r17.new, r21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x82 0x20
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gt(r2.new, r21)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.gt(r17.new, r21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x82 0x20
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gt(r2.new, r21)) jump:t
|
||||
# CHECK-NEXT: if (cmp.gt(r17.new, r21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0xc2 0x20
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gt(r2.new, r21)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.gt(r17.new, r21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0xc2 0x20
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gt(r2.new, r21)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.gt(r17.new, r21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x21
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gtu(r2.new, r21)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.gtu(r17.new, r21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x21
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gtu(r2.new, r21)) jump:t
|
||||
# CHECK-NEXT: if (cmp.gtu(r17.new, r21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x21
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gtu(r2.new, r21)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.gtu(r17.new, r21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x21
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gtu(r2.new, r21)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.gtu(r17.new, r21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x82 0x21
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gt(r21, r2.new)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.gt(r21, r17.new)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x82 0x21
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gt(r21, r2.new)) jump:t
|
||||
# CHECK-NEXT: if (cmp.gt(r21, r17.new)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0xc2 0x21
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gt(r21, r2.new)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.gt(r21, r17.new)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0xc2 0x21
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gt(r21, r2.new)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.gt(r21, r17.new)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x22
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gtu(r21, r2.new)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.gtu(r21, r17.new)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x22
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gtu(r21, r2.new)) jump:t
|
||||
# CHECK-NEXT: if (cmp.gtu(r21, r17.new)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x22
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gtu(r21, r2.new)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.gtu(r21, r17.new)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x22
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gtu(r21, r2.new)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.gtu(r21, r17.new)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x24
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.eq(r2.new, #21)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.eq(r17.new, #21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x24
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NETX: if (cmp.eq(r2.new, #21)) jump:t
|
||||
# CHECK-NETX: if (cmp.eq(r17.new, #21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x24
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.eq(r2.new, #21)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.eq(r17.new, #21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x24
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.eq(r2.new, #21)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.eq(r17.new, #21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x82 0x24
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gt(r2.new, #21)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.gt(r17.new, #21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x82 0x24
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gt(r2.new, #21)) jump:t
|
||||
# CHECK-NEXT: if (cmp.gt(r17.new, #21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0xc2 0x24
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gt(r2.new, #21)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.gt(r17.new, #21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0xc2 0x24
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gt(r2.new, #21)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.gt(r17.new, #21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x25
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gtu(r2.new, #21)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.gtu(r17.new, #21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x25
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gtu(r2.new, #21)) jump:t
|
||||
# CHECK-NEXT: if (cmp.gtu(r17.new, #21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x25
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gtu(r2.new, #21)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.gtu(r17.new, #21)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x25
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gtu(r2.new, #21)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.gtu(r17.new, #21)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xc0 0x82 0x25
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (tstbit(r2.new, #0)) jump:nt
|
||||
# CHECK-NEXT: if (tstbit(r17.new, #0)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xe0 0x82 0x25
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (tstbit(r2.new, #0)) jump:t
|
||||
# CHECK-NEXT: if (tstbit(r17.new, #0)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xc0 0xc2 0x25
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!tstbit(r2.new, #0)) jump:nt
|
||||
# CHECK-NEXT: if (!tstbit(r17.new, #0)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xe0 0xc2 0x25
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!tstbit(r2.new, #0)) jump:t
|
||||
# CHECK-NEXT: if (!tstbit(r17.new, #0)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xc0 0x02 0x26
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.eq(r2.new, #-1)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.eq(r17.new, #-1)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xe0 0x02 0x26
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.eq(r2.new, #-1)) jump:t
|
||||
# CHECK-NEXT: if (cmp.eq(r17.new, #-1)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xc0 0x42 0x26
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.eq(r2.new, #-1)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.eq(r17.new, #-1)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xe0 0x42 0x26
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.eq(r2.new, #-1)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.eq(r17.new, #-1)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xc0 0x82 0x26
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gt(r2.new, #-1)) jump:nt
|
||||
# CHECK-NEXT: if (cmp.gt(r17.new, #-1)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xe0 0x82 0x26
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (cmp.gt(r2.new, #-1)) jump:t
|
||||
# CHECK-NEXT: if (cmp.gt(r17.new, #-1)) jump:t
|
||||
0x11 0x40 0x71 0x70 0x92 0xc0 0xc2 0x26
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gt(r2.new, #-1)) jump:nt
|
||||
# CHECK-NEXT: if (!cmp.gt(r17.new, #-1)) jump:nt
|
||||
0x11 0x40 0x71 0x70 0x92 0xe0 0xc2 0x26
|
||||
# CHECK: r17 = r17
|
||||
# CHECK-NEXT: if (!cmp.gt(r2.new, #-1)) jump:t
|
||||
# CHECK-NEXT: if (!cmp.gt(r17.new, #-1)) jump:t
|
||||
|
@ -4,200 +4,209 @@
|
||||
# Store new-value byte
|
||||
0x1f 0x40 0x7f 0x70 0x82 0xf5 0xb1 0x3b
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memb(r17 + r21<<#3) = r2.new
|
||||
# CHECK-NEXT: memb(r17 + r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x11 0xc2 0xa0 0x48
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memb(#17) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x15 0xc2 0xb1 0xa1
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memb(r17+#21) = r2.new
|
||||
# CHECK-NEXT: memb(r17+#21) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x02 0xe2 0xb1 0xa9
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memb(r17 ++ I:circ(m1)) = r2.new
|
||||
# CHECK-NEXT: memb(r17 ++ I:circ(m1)) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x28 0xe2 0xb1 0xa9
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memb(r17 ++ #5:circ(m1)) = r2.new
|
||||
# CHECK-NEXT: memb(r17 ++ #5:circ(m1)) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x28 0xc2 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memb(r17++#5) = r2.new
|
||||
# CHECK-NEXT: memb(r17++#5) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x00 0xe2 0xb1 0xad
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memb(r17++m1) = r2.new
|
||||
# CHECK-NEXT: memb(r17++m1) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x00 0xe2 0xb1 0xaf
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memb(r17 ++ m1:brev) = r2.new
|
||||
# CHECK-NEXT: memb(r17 ++ m1:brev) = r31.new
|
||||
|
||||
# Store new-value byte conditionally
|
||||
0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x34
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memb(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (p3) memb(r17+r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x35
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memb(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memb(r17+r21<<#3) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x36
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memb(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memb(r17+r21<<#3) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x37
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memb(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memb(r17+r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xab 0xc2 0xb1 0x40
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memb(r17+#21) = r2.new
|
||||
# CHECK-NEXT: if (p3) memb(r17+#21) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xab 0xc2 0xb1 0x44
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memb(r17+#21) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memb(r17+#21) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xc2 0xb1 0x42
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memb(r17+#21) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memb(r17+#21) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xc2 0xb1 0x46
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memb(r17+#21) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memb(r17+#21) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x2b 0xe2 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memb(r17++#5) = r2.new
|
||||
# CHECK-NEXT: if (p3) memb(r17++#5) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x2f 0xe2 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memb(r17++#5) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memb(r17++#5) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xe2 0xb1 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memb(r17++#5) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memb(r17++#5) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xaf 0xe2 0xb1 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memb(r17++#5) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memb(r17++#5) = r31.new
|
||||
|
||||
# Store new-value halfword
|
||||
0x1f 0x40 0x7f 0x70 0x8a 0xf5 0xb1 0x3b
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memh(r17 + r21<<#3) = r2.new
|
||||
# CHECK-NEXT: memh(r17 + r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x15 0xca 0xa0 0x48
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memh(#42) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x15 0xca 0xb1 0xa1
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memh(r17+#42) = r2.new
|
||||
# CHECK-NEXT: memh(r17+#42) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x02 0xea 0xb1 0xa9
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memh(r17 ++ I:circ(m1)) = r2.new
|
||||
# CHECK-NEXT: memh(r17 ++ I:circ(m1)) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x28 0xea 0xb1 0xa9
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memh(r17 ++ #10:circ(m1)) = r2.new
|
||||
# CHECK-NEXT: memh(r17 ++ #10:circ(m1)) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x28 0xca 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memh(r17++#10) = r2.new
|
||||
# CHECK-NEXT: memh(r17++#10) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x00 0xea 0xb1 0xad
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memh(r17++m1) = r2.new
|
||||
# CHECK-NEXT: memh(r17++m1) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x00 0xea 0xb1 0xaf
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memh(r17 ++ m1:brev) = r2.new
|
||||
# CHECK-NEXT: memh(r17 ++ m1:brev) = r31.new
|
||||
|
||||
# Store new-value halfword conditionally
|
||||
0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x34
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memh(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (p3) memh(r17+r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x35
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memh(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memh(r17+r21<<#3) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x36
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memh(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memh(r17+r21<<#3) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x37
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memh(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memh(r17+r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xab 0xca 0xb1 0x40
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memh(r17+#42) = r2.new
|
||||
# CHECK-NEXT: if (p3) memh(r17+#42) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xab 0xca 0xb1 0x44
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memh(r17+#42) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memh(r17+#42) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xca 0xb1 0x42
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memh(r17+#42) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memh(r17+#42) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xca 0xb1 0x46
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memh(r17+#42) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memh(r17+#42) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x2b 0xea 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memh(r17++#10) = r2.new
|
||||
# CHECK-NEXT: if (p3) memh(r17++#10) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x2f 0xea 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memh(r17++#10) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memh(r17++#10) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xea 0xb1 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memh(r17++#10) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memh(r17++#10) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xaf 0xea 0xb1 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memh(r17++#10) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memh(r17++#10) = r31.new
|
||||
|
||||
# Store new-value word
|
||||
0x1f 0x40 0x7f 0x70 0x92 0xf5 0xb1 0x3b
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(r17 + r21<<#3) = r2.new
|
||||
# CHECK-NEXT: memw(r17 + r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x15 0xd2 0xa0 0x48
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(#84) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x15 0xd2 0xb1 0xa1
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(r17+#84) = r2.new
|
||||
0x1f 0x40 0x7f 0x70 0x28 0xf2 0xb1 0xa9
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(r17 ++ #20:circ(m1)) = r2.new
|
||||
# CHECK-NEXT: memw(r17+#84) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x02 0xf2 0xb1 0xa9
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(r17 ++ I:circ(m1)) = r2.new
|
||||
# CHECK-NEXT: memw(r17 ++ I:circ(m1)) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x28 0xf2 0xb1 0xa9
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(r17 ++ #20:circ(m1)) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x28 0xd2 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(r17++#20) = r2.new
|
||||
# CHECK-NEXT: memw(r17++#20) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x00 0xf2 0xb1 0xad
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(r17++m1) = r2.new
|
||||
# CHECK-NEXT: memw(r17++m1) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x00 0xf2 0xb1 0xaf
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: memw(r17 ++ m1:brev) = r2.new
|
||||
# CHECK-NEXT: memw(r17 ++ m1:brev) = r31.new
|
||||
|
||||
# Store new-value word conditionally
|
||||
0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x34
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memw(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (p3) memw(r17+r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x35
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memw(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memw(r17+r21<<#3) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x36
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memw(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memw(r17+r21<<#3) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x37
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memw(r17+r21<<#3) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memw(r17+r21<<#3) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xab 0xd2 0xb1 0x40
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memw(r17+#84) = r2.new
|
||||
# CHECK-NEXT: if (p3) memw(r17+#84) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0xab 0xd2 0xb1 0x44
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memw(r17+#84) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memw(r17+#84) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xd2 0xb1 0x42
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memw(r17+#84) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memw(r17+#84) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xd2 0xb1 0x46
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memw(r17+#84) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memw(r17+#84) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x2b 0xf2 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (p3) memw(r17++#20) = r2.new
|
||||
# CHECK-NEXT: if (p3) memw(r17++#20) = r31.new
|
||||
0x1f 0x40 0x7f 0x70 0x2f 0xf2 0xb1 0xab
|
||||
# CHECK: r31 = r31
|
||||
# CHECK-NEXT: if (!p3) memw(r17++#20) = r2.new
|
||||
# CHECK-NEXT: if (!p3) memw(r17++#20) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xf2 0xb1 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (p3.new) memw(r17++#20) = r2.new
|
||||
# CHECK-NEXT: if (p3.new) memw(r17++#20) = r31.new
|
||||
0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xaf 0xf2 0xb1 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: r31 = r31
|
||||
# CHECK-NEXT: if (!p3.new) memw(r17++#20) = r2.new
|
||||
# CHECK-NEXT: if (!p3.new) memw(r17++#20) = r31.new
|
||||
|
@ -1,11 +1,14 @@
|
||||
# RUN: llvm-mc -triple=hexagon -disassemble < %s | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.8 ST
|
||||
# XFAIL: *
|
||||
|
||||
# Store doubleword
|
||||
0x9e 0xf5 0xd1 0x3b
|
||||
# CHECK: memd(r17 + r21<<#3) = r31:30
|
||||
0x28 0xd4 0xc0 0x48
|
||||
# CHECK: memd(##320) = r21:20
|
||||
# CHECK: memd(#320) = r21:20
|
||||
0x02 0x40 0x00 0x00 0x28 0xd4 0xc0 0x48
|
||||
# CHECK: memd(##168) = r21:20
|
||||
0x15 0xd4 0xd1 0xa1
|
||||
# CHECK: memd(r17+#168) = r21:20
|
||||
0x02 0xf4 0xd1 0xa9
|
||||
@ -14,6 +17,8 @@
|
||||
# CHECK: memd(r17 ++ #40:circ(m1)) = r21:20
|
||||
0x28 0xd4 0xd1 0xab
|
||||
# CHECK: memd(r17++#40) = r21:20
|
||||
0x00 0x40 0x00 0x00 0xd5 0xfe 0xd1 0xad
|
||||
# CHECK: memd(r17<<#3 + ##21) = r31:30
|
||||
0x00 0xf4 0xd1 0xad
|
||||
# CHECK: memd(r17++m1) = r21:20
|
||||
0x00 0xf4 0xd1 0xaf
|
||||
@ -50,6 +55,16 @@
|
||||
0x03 0x40 0x45 0x85 0xaf 0xf4 0xd1 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) memd(r17++#40) = r21:20
|
||||
0x02 0x40 0x00 0x00 0xc3 0xd4 0xc2 0xaf
|
||||
# CHECK: if (p3) memd(##168) = r21:20
|
||||
0x02 0x40 0x00 0x00 0xc7 0xd4 0xc2 0xaf
|
||||
# CHECK: if (!p3) memd(##168) = r21:20
|
||||
0x03 0x40 0x45 0x85 0x02 0x40 0x00 0x00 0xc3 0xf4 0xc2 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (p3.new) memd(##168) = r21:20
|
||||
0x03 0x40 0x45 0x85 0x02 0x40 0x00 0x00 0xc7 0xf4 0xc2 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) memd(##168) = r21:20
|
||||
|
||||
# Store byte
|
||||
0x9f 0xf5 0x11 0x3b
|
||||
@ -57,6 +72,8 @@
|
||||
0x9f 0xca 0x11 0x3c
|
||||
# CHECK: memb(r17+#21)=#31
|
||||
0x15 0xd5 0x00 0x48
|
||||
# CHECK: memb(#21) = r21
|
||||
0x00 0x40 0x00 0x00 0x15 0xd5 0x00 0x48
|
||||
# CHECK: memb(##21) = r21
|
||||
0x15 0xd5 0x11 0xa1
|
||||
# CHECK: memb(r17+#21) = r21
|
||||
@ -66,6 +83,8 @@
|
||||
# CHECK: memb(r17 ++ #5:circ(m1)) = r21
|
||||
0x28 0xd5 0x11 0xab
|
||||
# CHECK: memb(r17++#5) = r21
|
||||
0x00 0x40 0x00 0x00 0xd5 0xff 0x11 0xad
|
||||
# CHECK: memb(r17<<#3 + ##21) = r31
|
||||
0x00 0xf5 0x11 0xad
|
||||
# CHECK: memb(r17++m1) = r21
|
||||
0x00 0xf5 0x11 0xaf
|
||||
@ -112,6 +131,16 @@
|
||||
0x03 0x40 0x45 0x85 0xaf 0xf5 0x11 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) memb(r17++#5) = r21
|
||||
0x00 0x40 0x00 0x00 0xab 0xd5 0x01 0xaf
|
||||
# CHECK: if (p3) memb(##21) = r21
|
||||
0x00 0x40 0x00 0x00 0xaf 0xd5 0x01 0xaf
|
||||
# CHECK: if (!p3) memb(##21) = r21
|
||||
0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xab 0xf5 0x01 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (p3.new) memb(##21) = r21
|
||||
0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xaf 0xf5 0x01 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) memb(##21) = r21
|
||||
|
||||
# Store halfword
|
||||
0x9f 0xf5 0x51 0x3b
|
||||
@ -120,10 +149,14 @@
|
||||
# CHECK: memh(r17 + r21<<#3) = r31.h
|
||||
0x95 0xcf 0x31 0x3c
|
||||
# CHECK: memh(r17+#62)=#21
|
||||
0x00 0x40 0x00 0x00 0x2a 0xd5 0x40 0x48
|
||||
# CHECK: memh(##42) = r21
|
||||
0x00 0x40 0x00 0x00 0x2a 0xd5 0x60 0x48
|
||||
# CHECK: memh(##42) = r21.h
|
||||
0x2a 0xd5 0x40 0x48
|
||||
# CHECK: memh(##84) = r21
|
||||
# CHECK: memh(#84) = r21
|
||||
0x2a 0xd5 0x60 0x48
|
||||
# CHECK: memh(##84) = r21.h
|
||||
# CHECK: memh(#84) = r21.h
|
||||
0x15 0xdf 0x51 0xa1
|
||||
# CHECK: memh(r17+#42) = r31
|
||||
0x15 0xdf 0x71 0xa1
|
||||
@ -138,8 +171,12 @@
|
||||
# CHECK: memh(r17 ++ #10:circ(m1)) = r21.h
|
||||
0x28 0xd5 0x51 0xab
|
||||
# CHECK: memh(r17++#10) = r21
|
||||
0x00 0x40 0x00 0x00 0xd5 0xff 0x51 0xad
|
||||
# CHECK: memh(r17<<#3 + ##21) = r31
|
||||
0x28 0xd5 0x71 0xab
|
||||
# CHECK: memh(r17++#10) = r21.h
|
||||
0x00 0x40 0x00 0x00 0xd5 0xff 0x71 0xad
|
||||
# CHECK: memh(r17<<#3 + ##21) = r31.h
|
||||
0x00 0xf5 0x51 0xad
|
||||
# CHECK: memh(r17++m1) = r21
|
||||
0x00 0xf5 0x71 0xad
|
||||
@ -220,22 +257,48 @@
|
||||
0x03 0x40 0x45 0x85 0xaf 0xf5 0x71 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) memh(r17++#10) = r21.h
|
||||
0x00 0x40 0x00 0x00 0xd3 0xd5 0x42 0xaf
|
||||
# CHECK: if (p3) memh(##42) = r21
|
||||
0x00 0x40 0x00 0x00 0xd3 0xd5 0x62 0xaf
|
||||
# CHECK: if (p3) memh(##42) = r21.h
|
||||
0x00 0x40 0x00 0x00 0xd7 0xd5 0x42 0xaf
|
||||
# CHECK: if (!p3) memh(##42) = r21
|
||||
0x00 0x40 0x00 0x00 0xd7 0xd5 0x62 0xaf
|
||||
# CHECK: if (!p3) memh(##42) = r21.h
|
||||
0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xd3 0xf5 0x42 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (p3.new) memh(##42) = r21
|
||||
0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xd3 0xf5 0x62 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (p3.new) memh(##42) = r21.h
|
||||
0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xd7 0xf5 0x42 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) memh(##42) = r21
|
||||
0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xd7 0xf5 0x62 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) memh(##42) = r21.h
|
||||
|
||||
# Store word
|
||||
0x9f 0xf5 0x91 0x3b
|
||||
# CHECK: memw(r17 + r21<<#3) = r31
|
||||
0x9f 0xca 0x51 0x3c
|
||||
# CHECK: memw(r17{{ *}}+{{ *}}#84)=#31
|
||||
0x15 0xdf 0x80 0x48
|
||||
# CHECK: memw(#84) = r31
|
||||
0x01 0x40 0x00 0x00 0x14 0xd5 0x80 0x48
|
||||
# CHECK: memw(##84) = r21
|
||||
0x9f 0xca 0x51 0x3c
|
||||
# CHECK: memw(r17+#84)=#31
|
||||
0x15 0xdf 0x91 0xa1
|
||||
# CHECK: memw(r17+#84) = r31
|
||||
0x14 0xd5 0x80 0x48
|
||||
# CHECK: memw(##80) = r21
|
||||
0x02 0xf5 0x91 0xa9
|
||||
# CHECK: memw(r17 ++ I:circ(m1)) = r21
|
||||
0x28 0xf5 0x91 0xa9
|
||||
# CHECK: memw(r17 ++ #20:circ(m1)) = r21
|
||||
0x28 0xd5 0x91 0xab
|
||||
# CHECK: memw(r17++#20) = r21
|
||||
0x00 0x40 0x00 0x00 0xd5 0xff 0x91 0xad
|
||||
# CHECK: memw(r17<<#3 + ##21) = r31
|
||||
0x00 0xf5 0x91 0xad
|
||||
# CHECK: memw(r17++m1) = r21
|
||||
0x00 0xf5 0x91 0xaf
|
||||
@ -282,7 +345,17 @@
|
||||
0x03 0x40 0x45 0x85 0xab 0xf5 0x91 0xab
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (p3.new) memw(r17++#20) = r21
|
||||
0x01 0x40 0x00 0x00 0xa3 0xd5 0x81 0xaf
|
||||
# CHECK: if (p3) memw(##84) = r21
|
||||
0x01 0x40 0x00 0x00 0xa7 0xd5 0x81 0xaf
|
||||
# CHECK: if (!p3) memw(##84) = r21
|
||||
0x03 0x40 0x45 0x85 0x01 0x40 0x00 0x00 0xa3 0xf5 0x81 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (p3.new) memw(##84) = r21
|
||||
0x03 0x40 0x45 0x85 0x01 0x40 0x00 0x00 0xa7 0xf5 0x81 0xaf
|
||||
# CHECK: p3 = r5
|
||||
# CHECK-NEXT: if (!p3.new) memw(##84) = r21
|
||||
|
||||
# Allocate stack frame
|
||||
0x1f 0xc0 0x9d 0xa0
|
||||
# CHECK: allocframe(#248)
|
||||
# CHECK: allocframe(#248)
|
||||
|
4
test/MC/Disassembler/Hexagon/too_many_instructions.txt
Normal file
4
test/MC/Disassembler/Hexagon/too_many_instructions.txt
Normal file
@ -0,0 +1,4 @@
|
||||
# RUN: llvm-mc -triple=hexagon -disassemble < %s 2>&1 | FileCheck %s
|
||||
|
||||
#CHECK: warning: invalid instruction encoding
|
||||
0x00 0x40 0x00 0x7f 0x00 0x40 0x00 0x7f 0x00 0x40 0x00 0x7f 0x00 0x40 0x00 0x7f 0x00 0xc0 0x00 0x7f
|
4
test/MC/Disassembler/Hexagon/too_many_loop_ends.txt
Normal file
4
test/MC/Disassembler/Hexagon/too_many_loop_ends.txt
Normal file
@ -0,0 +1,4 @@
|
||||
# RUN: llvm-mc -triple=hexagon -disassemble < %s 2>&1 | FileCheck %s
|
||||
|
||||
#CHECK: warning: invalid instruction encoding
|
||||
0x00 0x80 0x00 0x7f 0x00 0x80 0x00 0x7f 0x00 0x80 0x00 0x7f 0x00 0xc0 0x00 0x7f
|
9
test/MC/Disassembler/Hexagon/unextendable.txt
Normal file
9
test/MC/Disassembler/Hexagon/unextendable.txt
Normal file
@ -0,0 +1,9 @@
|
||||
# RUN: llvm-mc -triple=hexagon -disassemble < %s 2>&1 | FileCheck %s
|
||||
|
||||
#Invalid immediate extend duplex load/load
|
||||
#CHECK: warning: invalid instruction encoding
|
||||
0xfe 0x40 0x00 0x00 0x11 0x00 0x00 0x00
|
||||
|
||||
#Invalid immediate extend barrier
|
||||
#CHECK: warning: invalid instruction encoding
|
||||
0xfe 0x40 0x00 0x00 0x00 0xc0 0x00 0xa8
|
84
test/MC/Hexagon/instructions/alu32_alu.s
Normal file
84
test/MC/Hexagon/instructions/alu32_alu.s
Normal file
@ -0,0 +1,84 @@
|
||||
# RUN: llvm-mc -triple hexagon -filetype=obj %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.1.1 ALU32/ALU
|
||||
|
||||
# Add
|
||||
# CHECK: f1 c3 15 b0
|
||||
r17 = add(r21, #31)
|
||||
# CHECK: 11 df 15 f3
|
||||
r17 = add(r21, r31)
|
||||
# CHECK: 11 df 55 f6
|
||||
r17 = add(r21, r31):sat
|
||||
|
||||
# And
|
||||
# CHECK: f1 c3 15 76
|
||||
r17 = and(r21, #31)
|
||||
# CHECK: f1 c3 95 76
|
||||
r17 = or(r21, #31)
|
||||
# CHECK: 11 df 15 f1
|
||||
r17 = and(r21, r31)
|
||||
# CHECK: 11 df 35 f1
|
||||
r17 = or(r21, r31)
|
||||
# CHECK: 11 df 75 f1
|
||||
r17 = xor(r21, r31)
|
||||
# CHECK: 11 d5 9f f1
|
||||
r17 = and(r21, ~r31)
|
||||
# CHECK: 11 d5 bf f1
|
||||
r17 = or(r21, ~r31)
|
||||
|
||||
# Nop
|
||||
# CHECK: 00 c0 00 7f
|
||||
nop
|
||||
|
||||
# Subtract
|
||||
# CHECK: b1 c2 5f 76
|
||||
r17 = sub(#21, r31)
|
||||
# CHECK: 11 df 35 f3
|
||||
r17 = sub(r31, r21)
|
||||
# CHECK: 11 df d5 f6
|
||||
r17 = sub(r31, r21):sat
|
||||
|
||||
# Sign extend
|
||||
# CHECK: 11 c0 bf 70
|
||||
r17 = sxtb(r31)
|
||||
|
||||
# Transfer immediate
|
||||
# CHECK: 15 c0 31 72
|
||||
r17.h = #21
|
||||
# CHECK: 15 c0 31 71
|
||||
r17.l = #21
|
||||
# CHECK: f1 ff 5f 78
|
||||
r17 = #32767
|
||||
# CHECK: f1 ff df 78
|
||||
r17 = #-1
|
||||
|
||||
# Transfer register
|
||||
# CHECK: 11 c0 75 70
|
||||
r17 = r21
|
||||
|
||||
# Vector add halfwords
|
||||
# CHECK: 11 df 15 f6
|
||||
r17 = vaddh(r21, r31)
|
||||
# CHECK: 11 df 35 f6
|
||||
r17 = vaddh(r21, r31):sat
|
||||
# CHECK: 11 df 75 f6
|
||||
r17 = vadduh(r21, r31):sat
|
||||
|
||||
# Vector average halfwords
|
||||
# CHECK: 11 df 15 f7
|
||||
r17 = vavgh(r21, r31)
|
||||
# CHECK: 11 df 35 f7
|
||||
r17 = vavgh(r21, r31):rnd
|
||||
# CHECK: 11 df 75 f7
|
||||
r17 = vnavgh(r31, r21)
|
||||
|
||||
# Vector subtract halfwords
|
||||
# CHECK: 11 df 95 f6
|
||||
r17 = vsubh(r31, r21)
|
||||
# CHECK: 11 df b5 f6
|
||||
r17 = vsubh(r31, r21):sat
|
||||
# CHECK: 11 df f5 f6
|
||||
r17 = vsubuh(r31, r21):sat
|
||||
|
||||
# Zero extend
|
||||
# CHECK: 11 c0 d5 70
|
||||
r17 = zxth(r21)
|
40
test/MC/Hexagon/instructions/alu32_perm.s
Normal file
40
test/MC/Hexagon/instructions/alu32_perm.s
Normal file
@ -0,0 +1,40 @@
|
||||
# RUN: llvm-mc -triple hexagon -filetype=obj %s -o - | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.1.2 ALU32/PERM
|
||||
|
||||
# Combine words in to doublewords
|
||||
# CHECK: 11 df 95 f3
|
||||
r17 = combine(r31.h, r21.h)
|
||||
# CHECK: 11 df b5 f3
|
||||
r17 = combine(r31.h, r21.l)
|
||||
# CHECK: 11 df d5 f3
|
||||
r17 = combine(r31.l, r21.h)
|
||||
# CHECK: 11 df f5 f3
|
||||
r17 = combine(r31.l, r21.l)
|
||||
# CHECK: b0 e2 0f 7c
|
||||
r17:16 = combine(#21, #31)
|
||||
# CHECK: b0 e2 3f 73
|
||||
r17:16 = combine(#21, r31)
|
||||
# CHECK: f0 e3 15 73
|
||||
r17:16 = combine(r21, #31)
|
||||
# CHECK: 10 df 15 f5
|
||||
r17:16 = combine(r21, r31)
|
||||
|
||||
# Mux
|
||||
# CHECK: f1 c3 75 73
|
||||
r17 = mux(p3, r21, #31)
|
||||
# CHECK: b1 c2 ff 73
|
||||
r17 = mux(p3, #21, r31)
|
||||
# CHECK: b1 e2 8f 7b
|
||||
r17 = mux(p3, #21, #31)
|
||||
# CHECK: 71 df 15 f4
|
||||
r17 = mux(p3, r21, r31)
|
||||
|
||||
# Shift word by 16
|
||||
# CHECK: 11 c0 15 70
|
||||
r17 = aslh(r21)
|
||||
# CHECK: 11 c0 35 70
|
||||
r17 = asrh(r21)
|
||||
|
||||
# Pack high and low halfwords
|
||||
# CHECK: 10 df 95 f5
|
||||
r17:16 = packhl(r21, r31)
|
222
test/MC/Hexagon/instructions/alu32_pred.s
Normal file
222
test/MC/Hexagon/instructions/alu32_pred.s
Normal file
@ -0,0 +1,222 @@
|
||||
# RUN: llvm-mc -triple hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.1.3 ALU32/PRED
|
||||
|
||||
# Conditional add
|
||||
# CHECK: f1 c3 75 74
|
||||
if (p3) r17 = add(r21, #31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 e3 75 74
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = add(r21, #31) }
|
||||
# CHECK: f1 c3 f5 74
|
||||
if (!p3) r17 = add(r21, #31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 e3 f5 74
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = add(r21, #31) }
|
||||
# CHECK: 71 df 15 fb
|
||||
if (p3) r17 = add(r21, r31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 71 ff 15 fb
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = add(r21, r31) }
|
||||
# CHECK: f1 df 15 fb
|
||||
if (!p3) r17 = add(r21, r31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 15 fb
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = add(r21, r31) }
|
||||
|
||||
# Conditional shift halfword
|
||||
# CHECK: 11 e3 15 70
|
||||
if (p3) r17 = aslh(r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 e7 15 70
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = aslh(r21) }
|
||||
# CHECK: 11 eb 15 70
|
||||
if (!p3) r17 = aslh(r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 ef 15 70
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = aslh(r21) }
|
||||
# CHECK: 11 e3 35 70
|
||||
if (p3) r17 = asrh(r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 e7 35 70
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = asrh(r21) }
|
||||
# CHECK: 11 eb 35 70
|
||||
if (!p3) r17 = asrh(r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 ef 35 70
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = asrh(r21) }
|
||||
|
||||
# Conditional combine
|
||||
# CHECK: 70 df 15 fd
|
||||
if (p3) r17:16 = combine(r21, r31)
|
||||
# CHECK: f0 df 15 fd
|
||||
if (!p3) r17:16 = combine(r21, r31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 70 ff 15 fd
|
||||
{ p3 = r5
|
||||
if (p3.new) r17:16 = combine(r21, r31) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f0 ff 15 fd
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17:16 = combine(r21, r31) }
|
||||
|
||||
# Conditional logical operations
|
||||
# CHECK: 71 df 15 f9
|
||||
if (p3) r17 = and(r21, r31)
|
||||
# CHECK: f1 df 15 f9
|
||||
if (!p3) r17 = and(r21, r31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 71 ff 15 f9
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = and(r21, r31) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 15 f9
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = and(r21, r31) }
|
||||
# CHECK: 71 df 35 f9
|
||||
if (p3) r17 = or(r21, r31)
|
||||
# CHECK: f1 df 35 f9
|
||||
if (!p3) r17 = or(r21, r31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 71 ff 35 f9
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = or(r21, r31) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 35 f9
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = or(r21, r31) }
|
||||
# CHECK: 71 df 75 f9
|
||||
if (p3) r17 = xor(r21, r31)
|
||||
# CHECK: f1 df 75 f9
|
||||
if (!p3) r17 = xor(r21, r31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 71 ff 75 f9
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = xor(r21, r31) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 75 f9
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = xor(r21, r31) }
|
||||
|
||||
# Conditional subtract
|
||||
# CHECK: 71 df 35 fb
|
||||
if (p3) r17 = sub(r31, r21)
|
||||
# CHECK: f1 df 35 fb
|
||||
if (!p3) r17 = sub(r31, r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 71 ff 35 fb
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = sub(r31, r21) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 35 fb
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = sub(r31, r21) }
|
||||
|
||||
# Conditional sign extend
|
||||
# CHECK: 11 e3 b5 70
|
||||
if (p3) r17 = sxtb(r21)
|
||||
# CHECK: 11 eb b5 70
|
||||
if (!p3) r17 = sxtb(r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 e7 b5 70
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = sxtb(r21) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 ef b5 70
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = sxtb(r21) }
|
||||
# CHECK: 11 e3 f5 70
|
||||
if (p3) r17 = sxth(r21)
|
||||
# CHECK: 11 eb f5 70
|
||||
if (!p3) r17 = sxth(r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 e7 f5 70
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = sxth(r21) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 ef f5 70
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = sxth(r21) }
|
||||
|
||||
# Conditional transfer
|
||||
# CHECK: b1 c2 60 7e
|
||||
if (p3) r17 = #21
|
||||
# CHECK: b1 c2 e0 7e
|
||||
if (!p3) r17 = #21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 e2 60 7e
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = #21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 e2 e0 7e
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = #21 }
|
||||
|
||||
# Conditional zero extend
|
||||
# CHECK: 11 e3 95 70
|
||||
if (p3) r17 = zxtb(r21)
|
||||
# CHECK: 11 eb 95 70
|
||||
if (!p3) r17 = zxtb(r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 e7 95 70
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = zxtb(r21) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 ef 95 70
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = zxtb(r21) }
|
||||
# CHECK: 11 e3 d5 70
|
||||
if (p3) r17 = zxth(r21)
|
||||
# CHECK: 11 eb d5 70
|
||||
if (!p3) r17 = zxth(r21)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 e7 d5 70
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = zxth(r21) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 11 ef d5 70
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = zxth(r21) }
|
||||
|
||||
# Compare
|
||||
# CHECK: e3 c3 15 75
|
||||
p3 = cmp.eq(r21, #31)
|
||||
# CHECK: f3 c3 15 75
|
||||
p3 = !cmp.eq(r21, #31)
|
||||
# CHECK: e3 c3 55 75
|
||||
p3 = cmp.gt(r21, #31)
|
||||
# CHECK: f3 c3 55 75
|
||||
p3 = !cmp.gt(r21, #31)
|
||||
# CHECK: e3 c3 95 75
|
||||
p3 = cmp.gtu(r21, #31)
|
||||
# CHECK: f3 c3 95 75
|
||||
p3 = !cmp.gtu(r21, #31)
|
||||
# CHECK: 03 df 15 f2
|
||||
p3 = cmp.eq(r21, r31)
|
||||
# CHECK: 13 df 15 f2
|
||||
p3 = !cmp.eq(r21, r31)
|
||||
# CHECK: 03 df 55 f2
|
||||
p3 = cmp.gt(r21, r31)
|
||||
# CHECK: 13 df 55 f2
|
||||
p3 = !cmp.gt(r21, r31)
|
||||
# CHECK: 03 df 75 f2
|
||||
p3 = cmp.gtu(r21, r31)
|
||||
# CHECK: 13 df 75 f2
|
||||
p3 = !cmp.gtu(r21, r31)
|
||||
|
||||
# Compare to general register
|
||||
# CHECK: f1 e3 55 73
|
||||
r17 = cmp.eq(r21, #31)
|
||||
# CHECK: f1 e3 75 73
|
||||
r17 = !cmp.eq(r21, #31)
|
||||
# CHECK: 11 df 55 f3
|
||||
r17 = cmp.eq(r21, r31)
|
||||
# CHECK: 11 df 75 f3
|
||||
r17 = !cmp.eq(r21, r31)
|
78
test/MC/Hexagon/instructions/cr.s
Normal file
78
test/MC/Hexagon/instructions/cr.s
Normal file
@ -0,0 +1,78 @@
|
||||
# RUN: llvm-mc --triple hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.2 CR
|
||||
|
||||
# Corner detection acceleration
|
||||
# CHECK: 93 e1 12 6b
|
||||
p3 = !fastcorner9(p2, p1)
|
||||
# CHECK: 91 e3 02 6b
|
||||
p1 = fastcorner9(p2, p3)
|
||||
|
||||
# Logical reductions on predicates
|
||||
# CHECK: 01 c0 82 6b
|
||||
p1 = any8(p2)
|
||||
# CHECK: 01 c0 a2 6b
|
||||
p1 = all8(p2)
|
||||
|
||||
# Looping instructions
|
||||
# CHECK: 00 c0 15 60
|
||||
loop0(0, r21)
|
||||
# CHECK: 00 c0 35 60
|
||||
loop1(0, r21)
|
||||
# CHECK: 60 c0 00 69
|
||||
loop0(0, #12)
|
||||
# CHECK: 60 c0 20 69
|
||||
loop1(0, #12)
|
||||
|
||||
# Add to PC
|
||||
# CHECK: 91 ca 49 6a
|
||||
r17 = add(pc, #21)
|
||||
|
||||
# Pipelined loop instructions
|
||||
# CHECK: 00 c0 b5 60
|
||||
p3 = sp1loop0(0, r21)
|
||||
# CHECK: 00 c0 d5 60
|
||||
p3 = sp2loop0(0, r21)
|
||||
# CHECK: 00 c0 f5 60
|
||||
p3 = sp3loop0(0, r21)
|
||||
# CHECK: a1 c0 a0 69
|
||||
p3 = sp1loop0(0, #21)
|
||||
# CHECK: a1 c0 c0 69
|
||||
p3 = sp2loop0(0, #21)
|
||||
# CHECK: a1 c0 e0 69
|
||||
p3 = sp3loop0(0, #21)
|
||||
|
||||
# Logical operations on predicates
|
||||
# CHECK: 01 c3 02 6b
|
||||
p1 = and(p3, p2)
|
||||
# CHECK: c1 c3 12 6b
|
||||
p1 = and(p2, and(p3, p3))
|
||||
# CHECK: 01 c3 22 6b
|
||||
p1 = or(p3, p2)
|
||||
# CHECK: c1 c3 32 6b
|
||||
p1 = and(p2, or(p3, p3))
|
||||
# CHECK: 01 c3 42 6b
|
||||
p1 = xor(p2, p3)
|
||||
# CHECK: c1 c3 52 6b
|
||||
p1 = or(p2, and(p3, p3))
|
||||
# CHECK: 01 c2 63 6b
|
||||
p1 = and(p2, !p3)
|
||||
# CHECK: c1 c3 72 6b
|
||||
p1 = or(p2, or(p3, p3))
|
||||
# CHECK: c1 c3 92 6b
|
||||
p1 = and(p2, and(p3, !p3))
|
||||
# CHECK: c1 c3 b2 6b
|
||||
p1 = and(p2, or(p3, !p3))
|
||||
# CHECK: 01 c0 c2 6b
|
||||
p1 = not(p2)
|
||||
# CHECK: c1 c3 d2 6b
|
||||
p1 = or(p2, and(p3, !p3))
|
||||
# CHECK: 01 c2 e3 6b
|
||||
p1 = or(p2, !p3)
|
||||
# CHECK: c1 c3 f2 6b
|
||||
p1 = or(p2, or(p3, !p3))
|
||||
|
||||
# User control register transfer
|
||||
# CHECK: 0d c0 35 62
|
||||
cs1 = r21
|
||||
# CHECK: 11 c0 0d 6a
|
||||
r17 = cs1
|
207
test/MC/Hexagon/instructions/j.s
Normal file
207
test/MC/Hexagon/instructions/j.s
Normal file
@ -0,0 +1,207 @@
|
||||
# RUN: llvm-mc -triple hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.4 J
|
||||
# XFAIL: *
|
||||
|
||||
# Call subroutine
|
||||
# CHECK: 00 c0 00 5a
|
||||
call 0
|
||||
# CHECK: 00 c3 00 5d
|
||||
if (p3) call 0
|
||||
# CHECK: 00 c3 20 5d
|
||||
if (!p3) call 0
|
||||
|
||||
# Compare and jump
|
||||
# CHECK: 00 c0 89 11
|
||||
{ p0 = cmp.eq(r17,#-1); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 c1 89 11
|
||||
{ p0 = cmp.gt(r17,#-1); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 c3 89 11
|
||||
{ p0 = tstbit(r17, #0); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 e0 89 11
|
||||
{ p0 = cmp.eq(r17,#-1); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 e1 89 11
|
||||
{ p0 = cmp.gt(r17,#-1); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 e3 89 11
|
||||
{ p0 = tstbit(r17, #0); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 c0 c9 11
|
||||
{ p0 = cmp.eq(r17,#-1); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 c1 c9 11
|
||||
{ p0 = cmp.gt(r17,#-1); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 c3 c9 11
|
||||
{ p0 = tstbit(r17, #0); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 e0 c9 11
|
||||
{ p0 = cmp.eq(r17,#-1); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 e1 c9 11
|
||||
{ p0 = cmp.gt(r17,#-1); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 e3 c9 11
|
||||
{ p0 = tstbit(r17, #0); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 d5 09 10
|
||||
{ p0 = cmp.eq(r17, #21); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 09 10
|
||||
{ p0 = cmp.eq(r17, #21); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 d5 49 10
|
||||
{ p0 = cmp.eq(r17, #21); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 49 10
|
||||
{ p0 = cmp.eq(r17, #21); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 d5 89 10
|
||||
{ p0 = cmp.gt(r17, #21); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 89 10
|
||||
{ p0 = cmp.gt(r17, #21); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 d5 c9 10
|
||||
{ p0 = cmp.gt(r17, #21); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 c9 10
|
||||
{ p0 = cmp.gt(r17, #21); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 d5 09 11
|
||||
{ p0 = cmp.gtu(r17, #21); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 09 11
|
||||
{ p0 = cmp.gtu(r17, #21); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 d5 49 11
|
||||
{ p0 = cmp.gtu(r17, #21); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 49 11
|
||||
{ p0 = cmp.gtu(r17, #21); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 c0 89 13
|
||||
{ p1 = cmp.eq(r17,#-1); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 c1 89 13
|
||||
{ p1 = cmp.gt(r17,#-1); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 c3 89 13
|
||||
{ p1 = tstbit(r17, #0); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 e0 89 13
|
||||
{ p1 = cmp.eq(r17,#-1); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 e1 89 13
|
||||
{ p1 = cmp.gt(r17,#-1); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 e3 89 13
|
||||
{ p1 = tstbit(r17, #0); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 c0 c9 13
|
||||
{ p1 = cmp.eq(r17,#-1); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 c1 c9 13
|
||||
{ p1 = cmp.gt(r17,#-1); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 c3 c9 13
|
||||
{ p1 = tstbit(r17, #0); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 e0 c9 13
|
||||
{ p1 = cmp.eq(r17,#-1); if (!p1.new) jump:t 0 }
|
||||
# CHECK: 00 e1 c9 13
|
||||
{ p1 = cmp.gt(r17,#-1); if (!p1.new) jump:t 0 }
|
||||
# CHECK: 00 e3 c9 13
|
||||
{ p1 = tstbit(r17, #0); if (!p1.new) jump:t 0 }
|
||||
# CHECK: 00 d5 09 12
|
||||
{ p1 = cmp.eq(r17, #21); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 09 12
|
||||
{ p1 = cmp.eq(r17, #21); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 d5 49 12
|
||||
{ p1 = cmp.eq(r17, #21); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 49 12
|
||||
{ p1 = cmp.eq(r17, #21); if (!p1.new) jump:t 0 }
|
||||
# CHECK: 00 d5 89 12
|
||||
{ p1 = cmp.gt(r17, #21); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 89 12
|
||||
{ p1 = cmp.gt(r17, #21); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 d5 c9 12
|
||||
{ p1 = cmp.gt(r17, #21); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 c9 12
|
||||
{ p1 = cmp.gt(r17, #21); if (!p1.new) jump:t 0 }
|
||||
# CHECK: 00 d5 09 13
|
||||
{ p1 = cmp.gtu(r17, #21); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 09 13
|
||||
{ p1 = cmp.gtu(r17, #21); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 d5 49 13
|
||||
{ p1 = cmp.gtu(r17, #21); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 f5 49 13
|
||||
{ p1 = cmp.gtu(r17, #21); if (!p1.new) jump:t 0 }
|
||||
# CHECK: 00 cd 09 14
|
||||
{ p0 = cmp.eq(r17, r21); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 dd 09 14
|
||||
{ p1 = cmp.eq(r17, r21); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 ed 09 14
|
||||
{ p0 = cmp.eq(r17, r21); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 fd 09 14
|
||||
{ p1 = cmp.eq(r17, r21); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 cd 49 14
|
||||
{ p0 = cmp.eq(r17, r21); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 dd 49 14
|
||||
{ p1 = cmp.eq(r17, r21); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 ed 49 14
|
||||
{ p0 = cmp.eq(r17, r21); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 fd 49 14
|
||||
{ p1 = cmp.eq(r17, r21); if (!p1.new) jump:t 0 }
|
||||
# CHECK: 00 cd 89 14
|
||||
{ p0 = cmp.gt(r17, r21); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 dd 89 14
|
||||
{ p1 = cmp.gt(r17, r21); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 ed 89 14
|
||||
{ p0 = cmp.gt(r17, r21); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 fd 89 14
|
||||
{ p1 = cmp.gt(r17, r21); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 cd c9 14
|
||||
{ p0 = cmp.gt(r17, r21); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 dd c9 14
|
||||
{ p1 = cmp.gt(r17, r21); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 ed c9 14
|
||||
{ p0 = cmp.gt(r17, r21); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 fd c9 14
|
||||
{ p1 = cmp.gt(r17, r21); if (!p1.new) jump:t 0 }
|
||||
# CHECK: 00 cd 09 15
|
||||
{ p0 = cmp.gtu(r17, r21); if (p0.new) jump:nt 0 }
|
||||
# CHECK: 00 dd 09 15
|
||||
{ p1 = cmp.gtu(r17, r21); if (p1.new) jump:nt 0 }
|
||||
# CHECK: 00 ed 09 15
|
||||
{ p0 = cmp.gtu(r17, r21); if (p0.new) jump:t 0 }
|
||||
# CHECK: 00 fd 09 15
|
||||
{ p1 = cmp.gtu(r17, r21); if (p1.new) jump:t 0 }
|
||||
# CHECK: 00 cd 49 15
|
||||
{ p0 = cmp.gtu(r17, r21); if (!p0.new) jump:nt 0 }
|
||||
# CHECK: 00 dd 49 15
|
||||
{ p1 = cmp.gtu(r17, r21); if (!p1.new) jump:nt 0 }
|
||||
# CHECK: 00 ed 49 15
|
||||
{ p0 = cmp.gtu(r17, r21); if (!p0.new) jump:t 0 }
|
||||
# CHECK: 00 fd 49 15
|
||||
{ p1 = cmp.gtu(r17, r21); if (!p1.new) jump:t 0 }
|
||||
|
||||
# Jump to address
|
||||
# CHECK: 00 c0 00 58
|
||||
jump 0
|
||||
# CHECK: 00 c3 00 5c
|
||||
if (p3) jump 0
|
||||
# CHECK: 00 c3 20 5c
|
||||
if (!p3) jump 0
|
||||
|
||||
# Jump to address conditioned on new predicate
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 cb 00 5c
|
||||
{ p3 = r5
|
||||
if (p3.new) jump:nt 0 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 db 00 5c
|
||||
{ p3 = r5
|
||||
if (p3.new) jump:t 0 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 cb 20 5c
|
||||
{ p3 = r5
|
||||
if (!p3.new) jump:nt 0 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 db 20 5c
|
||||
{ p3 = r5
|
||||
if (!p3.new) jump:t 0 }
|
||||
|
||||
# Jump to address conditioned on register value
|
||||
# CHECK: 00 c0 11 61
|
||||
if (r17!=#0) jump:nt 0
|
||||
# CHECK: 00 d0 11 61
|
||||
if (r17!=#0) jump:t 0
|
||||
# CHECK: 00 c0 51 61
|
||||
if (r17>=#0) jump:nt 0
|
||||
# CHECK: 00 d0 51 61
|
||||
if (r17>=#0) jump:t 0
|
||||
# CHECK: 00 c0 91 61
|
||||
if (r17==#0) jump:nt 0
|
||||
# CHECK: 00 d0 91 61
|
||||
if (r17==#0) jump:t 0
|
||||
# CHECK: 00 c0 d1 61
|
||||
if (r17<=#0) jump:nt 0
|
||||
# CHECK: 00 d0 d1 61
|
||||
if (r17<=#0) jump:t 0
|
||||
|
||||
# Transfer and jump
|
||||
# CHECK: 00 d5 09 16
|
||||
{ r17 = #21 ; jump 0}
|
||||
# CHECK: 00 c9 0d 17
|
||||
{ r17 = r21 ; jump 0 }
|
38
test/MC/Hexagon/instructions/jr.s
Normal file
38
test/MC/Hexagon/instructions/jr.s
Normal file
@ -0,0 +1,38 @@
|
||||
# RUN: llvm-mc -triple hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.3 JR
|
||||
|
||||
# Call subroutine from register
|
||||
# CHECK: 00 c0 b5 50
|
||||
callr r21
|
||||
# CHECK: 00 c1 15 51
|
||||
if (p1) callr r21
|
||||
# CHECK: 00 c3 35 51
|
||||
if (!p3) callr r21
|
||||
|
||||
# Hint an indirect jump address
|
||||
# CHECK: 00 c0 b5 52
|
||||
hintjr(r21)
|
||||
|
||||
# Jump to address from register
|
||||
# CHECK: 00 c0 95 52
|
||||
jumpr r21
|
||||
# CHECK: 00 c1 55 53
|
||||
if (p1) jumpr r21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 cb 55 53
|
||||
{ p3 = r5
|
||||
if (p3.new) jumpr:nt r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 db 55 53
|
||||
{ p3 = r5
|
||||
if (p3.new) jumpr:t r21 }
|
||||
# CHECK: 00 c3 75 53
|
||||
if (!p3) jumpr r21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 cb 75 53
|
||||
{ p3 = r5
|
||||
if (!p3.new) jumpr:nt r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 db 75 53
|
||||
{ p3 = r5
|
||||
if (!p3.new) jumpr:t r21 }
|
499
test/MC/Hexagon/instructions/ld.s
Normal file
499
test/MC/Hexagon/instructions/ld.s
Normal file
@ -0,0 +1,499 @@
|
||||
# RUN: llvm-mc -triple hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.5 LD
|
||||
# XFAIL: *
|
||||
|
||||
# Load doubleword
|
||||
# CHECK: 90 ff d5 3a
|
||||
r17:16 = memd(r21 + r31<<#3)
|
||||
# CHECK: b0 c2 c0 49
|
||||
r17:16 = memd(#168)
|
||||
# CHECK: 02 40 00 00
|
||||
# CHECK-NEXT: 10 c5 c0 49
|
||||
r17:16 = memd(##168)
|
||||
# CHECK: d0 c0 d5 91
|
||||
r17:16 = memd(r21 + #48)
|
||||
# CHECK: b0 e0 d5 99
|
||||
r17:16 = memd(r21 ++ #40:circ(m1))
|
||||
# CHECK: 10 e2 d5 99
|
||||
r17:16 = memd(r21 ++ I:circ(m1))
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 70 d7 d5 9b
|
||||
r17:16 = memd(r21 = ##31)
|
||||
# CHECK: b0 c0 d5 9b
|
||||
r17:16 = memd(r21++#40)
|
||||
# CHECK: 10 e0 d5 9d
|
||||
r17:16 = memd(r21++m1)
|
||||
# CHECK: 10 e0 d5 9f
|
||||
r17:16 = memd(r21 ++ m1:brev)
|
||||
|
||||
# Load doubleword conditionally
|
||||
# CHECK: f0 ff d5 30
|
||||
if (p3) r17:16 = memd(r21+r31<<#3)
|
||||
# CHECK: f0 ff d5 31
|
||||
if (!p3) r17:16 = memd(r21+r31<<#3)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f0 ff d5 32
|
||||
{ p3 = r5
|
||||
if (p3.new) r17:16 = memd(r21+r31<<#3) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f0 ff d5 33
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17:16 = memd(r21+r31<<#3) }
|
||||
# CHECK: 70 d8 d5 41
|
||||
if (p3) r17:16 = memd(r21 + #24)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 70 d8 d5 43
|
||||
{ p3 = r5
|
||||
if (p3.new) r17:16 = memd(r21 + #24) }
|
||||
# CHECK: 70 d8 d5 45
|
||||
if (!p3) r17:16 = memd(r21 + #24)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 70 d8 d5 47
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17:16 = memd(r21 + #24) }
|
||||
# CHECK: b0 e6 d5 9b
|
||||
if (p3) r17:16 = memd(r21++#40)
|
||||
# CHECK: b0 ee d5 9b
|
||||
if (!p3) r17:16 = memd(r21++#40)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b0 f6 d5 9b
|
||||
{ p3 = r5
|
||||
if (p3.new) r17:16 = memd(r21++#40) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b0 fe d5 9b
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17:16 = memd(r21++#40) }
|
||||
|
||||
# Load byte
|
||||
# CHECK: 91 ff 15 3a
|
||||
r17 = memb(r21 + r31<<#3)
|
||||
# CHECK: b1 c2 00 49
|
||||
r17 = memb(#21)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: b1 c2 00 49
|
||||
r17 = memb(##21)
|
||||
# CHECK: f1 c3 15 91
|
||||
r17 = memb(r21 + #31)
|
||||
# CHECK: b1 e0 15 99
|
||||
r17 = memb(r21 ++ #5:circ(m1))
|
||||
# CHECK: 11 e2 15 99
|
||||
r17 = memb(r21 ++ I:circ(m1))
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 71 d7 15 9b
|
||||
r17 = memb(r21 = ##31)
|
||||
# CHECK: b1 c0 15 9b
|
||||
r17 = memb(r21++#5)
|
||||
# CHECK: 11 e0 15 9d
|
||||
r17 = memb(r21++m1)
|
||||
# CHECK: 11 e0 15 9f
|
||||
r17 = memb(r21 ++ m1:brev)
|
||||
|
||||
# Load byte conditionally
|
||||
# CHECK: f1 ff 15 30
|
||||
if (p3) r17 = memb(r21+r31<<#3)
|
||||
# CHECK: f1 ff 15 31
|
||||
if (!p3) r17 = memb(r21+r31<<#3)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 15 32
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memb(r21+r31<<#3) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 15 33
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memb(r21+r31<<#3) }
|
||||
# CHECK: 91 dd 15 41
|
||||
if (p3) r17 = memb(r21 + #44)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 91 dd 15 43
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memb(r21 + #44) }
|
||||
# CHECK: 91 dd 15 45
|
||||
if (!p3) r17 = memb(r21 + #44)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 91 dd 15 47
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memb(r21 + #44) }
|
||||
# CHECK: b1 e6 15 9b
|
||||
if (p3) r17 = memb(r21++#5)
|
||||
# CHECK: b1 ee 15 9b
|
||||
if (!p3) r17 = memb(r21++#5)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 f6 15 9b
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memb(r21++#5) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 fe 15 9b
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memb(r21++#5) }
|
||||
|
||||
# Load byte into shifted vector
|
||||
# CHECK: f0 c3 95 90
|
||||
r17:16 = memb_fifo(r21 + #31)
|
||||
# CHECK: b0 e0 95 98
|
||||
r17:16 = memb_fifo(r21 ++ #5:circ(m1))
|
||||
# CHECK: 10 e2 95 98
|
||||
r17:16 = memb_fifo(r21 ++ I:circ(m1))
|
||||
|
||||
# Load half into shifted vector
|
||||
# CHECK: f0 c3 55 90
|
||||
r17:16 = memh_fifo(r21 + #62)
|
||||
# CHECK: b0 e0 55 98
|
||||
r17:16 = memh_fifo(r21 ++ #10:circ(m1))
|
||||
# CHECK: 10 e2 55 98
|
||||
r17:16 = memh_fifo(r21 ++ I:circ(m1))
|
||||
|
||||
# Load halfword
|
||||
# CHECK: 91 ff 55 3a
|
||||
r17 = memh(r21 + r31<<#3)
|
||||
# CHECK: b1 c2 40 49
|
||||
r17 = memh(#42)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 51 c5 40 49
|
||||
r17 = memh(##42)
|
||||
# CHECK: f1 c3 55 91
|
||||
r17 = memh(r21 + #62)
|
||||
# CHECK: b1 e0 55 99
|
||||
r17 = memh(r21 ++ #10:circ(m1))
|
||||
# CHECK: 11 e2 55 99
|
||||
r17 = memh(r21 ++ I:circ(m1))
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 71 d7 55 9b
|
||||
r17 = memh(r21 = ##31)
|
||||
# CHECK: b1 c0 55 9b
|
||||
r17 = memh(r21++#10)
|
||||
# CHECK: 11 e0 55 9d
|
||||
r17 = memh(r21++m1)
|
||||
# CHECK: 11 e0 55 9f
|
||||
r17 = memh(r21 ++ m1:brev)
|
||||
|
||||
# Load halfword conditionally
|
||||
# CHECK: f1 ff 55 30
|
||||
if (p3) r17 = memh(r21+r31<<#3)
|
||||
# CHECK: f1 ff 55 31
|
||||
if (!p3) r17 = memh(r21+r31<<#3)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 55 32
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memh(r21+r31<<#3) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 55 33
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memh(r21+r31<<#3) }
|
||||
# CHECK: b1 e6 55 9b
|
||||
if (p3) r17 = memh(r21++#10)
|
||||
# CHECK: b1 ee 55 9b
|
||||
if (!p3) r17 = memh(r21++#10)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 f6 55 9b
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memh(r21++#10) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 fe 55 9b
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memh(r21++#10) }
|
||||
# CHECK: f1 db 55 41
|
||||
if (p3) r17 = memh(r21 + #62)
|
||||
# CHECK: f1 db 55 45
|
||||
if (!p3) r17 = memh(r21 + #62)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 db 55 43
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memh(r21 + #62) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 db 55 47
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memh(r21 + #62) }
|
||||
|
||||
# Load unsigned byte
|
||||
# CHECK: 91 ff 35 3a
|
||||
r17 = memub(r21 + r31<<#3)
|
||||
# CHECK: b1 c2 20 49
|
||||
r17 = memub(#21)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: b1 c2 20 49
|
||||
r17 = memub(##21)
|
||||
# CHECK: f1 c3 35 91
|
||||
r17 = memub(r21 + #31)
|
||||
# CHECK: b1 e0 35 99
|
||||
r17 = memub(r21 ++ #5:circ(m1))
|
||||
# CHECK: 11 e2 35 99
|
||||
r17 = memub(r21 ++ I:circ(m1))
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 71 d7 35 9b
|
||||
r17 = memub(r21 = ##31)
|
||||
# CHECK: b1 c0 35 9b
|
||||
r17 = memub(r21++#5)
|
||||
# CHECK: 11 e0 35 9d
|
||||
r17 = memub(r21++m1)
|
||||
# CHECK: 11 e0 35 9f
|
||||
r17 = memub(r21 ++ m1:brev)
|
||||
|
||||
# Load unsigned byte conditionally
|
||||
# CHECK: f1 ff 35 30
|
||||
if (p3) r17 = memub(r21+r31<<#3)
|
||||
# CHECK: f1 ff 35 31
|
||||
if (!p3) r17 = memub(r21+r31<<#3)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 35 32
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memub(r21+r31<<#3) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 35 33
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memub(r21+r31<<#3) }
|
||||
# CHECK: f1 db 35 41
|
||||
if (p3) r17 = memub(r21 + #31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 db 35 43
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memub(r21 + #31) }
|
||||
# CHECK: f1 db 35 45
|
||||
if (!p3) r17 = memub(r21 + #31)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 db 35 47
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memub(r21 + #31) }
|
||||
# CHECK: b1 e6 35 9b
|
||||
if (p3) r17 = memub(r21++#5)
|
||||
# CHECK: b1 ee 35 9b
|
||||
if (!p3) r17 = memub(r21++#5)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 f6 35 9b
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memub(r21++#5) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 fe 35 9b
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memub(r21++#5) }
|
||||
|
||||
# Load unsigned halfword
|
||||
# CHECK: 91 ff 75 3a
|
||||
r17 = memuh(r21 + r31<<#3)
|
||||
# CHECK: b1 c2 60 49
|
||||
r17 = memuh(#42)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 51 c5 60 49
|
||||
r17 = memuh(##42)
|
||||
# CHECK: b1 c2 75 91
|
||||
r17 = memuh(r21 + #42)
|
||||
# CHECK: b1 e0 75 99
|
||||
r17 = memuh(r21 ++ #10:circ(m1))
|
||||
# CHECK: 11 e2 75 99
|
||||
r17 = memuh(r21 ++ I:circ(m1))
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 71 d7 75 9b
|
||||
r17 = memuh(r21 = ##31)
|
||||
# CHECK: b1 c0 75 9b
|
||||
r17 = memuh(r21++#10)
|
||||
# CHECK: 11 e0 75 9d
|
||||
r17 = memuh(r21++m1)
|
||||
# CHECK: 11 e0 75 9f
|
||||
r17 = memuh(r21 ++ m1:brev)
|
||||
|
||||
# Load unsigned halfword conditionally
|
||||
# CHECK: f1 ff 75 30
|
||||
if (p3) r17 = memuh(r21+r31<<#3)
|
||||
# CHECK: f1 ff 75 31
|
||||
if (!p3) r17 = memuh(r21+r31<<#3)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 75 32
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memuh(r21+r31<<#3) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 75 33
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memuh(r21+r31<<#3) }
|
||||
# CHECK: b1 da 75 41
|
||||
if (p3) r17 = memuh(r21 + #42)
|
||||
# CHECK: b1 da 75 45
|
||||
if (!p3) r17 = memuh(r21 + #42)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 da 75 43
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memuh(r21 + #42) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 da 75 47
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memuh(r21 + #42) }
|
||||
# CHECK: b1 e6 75 9b
|
||||
if (p3) r17 = memuh(r21++#10)
|
||||
# CHECK: b1 ee 75 9b
|
||||
if (!p3) r17 = memuh(r21++#10)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 f6 75 9b
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memuh(r21++#10) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 fe 75 9b
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memuh(r21++#10) }
|
||||
|
||||
# Load word
|
||||
# CHECK: 91 ff 95 3a
|
||||
r17 = memw(r21 + r31<<#3)
|
||||
# CHECK: b1 c2 80 49
|
||||
r17 = memw(#84)
|
||||
# CHECK: 01 40 00 00
|
||||
# CHECK-NEXT: 91 c2 80 49
|
||||
r17 = memw(##84)
|
||||
# CHECK: b1 c2 95 91
|
||||
r17 = memw(r21 + #84)
|
||||
# CHECK: b1 e0 95 99
|
||||
r17 = memw(r21 ++ #20:circ(m1))
|
||||
# CHECK: 11 e2 95 99
|
||||
r17 = memw(r21 ++ I:circ(m1))
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 71 d7 95 9b
|
||||
r17 = memw(r21 = ##31)
|
||||
# CHECK: b1 c0 95 9b
|
||||
r17 = memw(r21++#20)
|
||||
# CHECK: 11 e0 95 9d
|
||||
r17 = memw(r21++m1)
|
||||
# CHECK: 11 e0 95 9f
|
||||
r17 = memw(r21 ++ m1:brev)
|
||||
|
||||
# Load word conditionally
|
||||
# CHECK: f1 ff 95 30
|
||||
if (p3) r17 = memw(r21+r31<<#3)
|
||||
# CHECK: f1 ff 95 31
|
||||
if (!p3) r17 = memw(r21+r31<<#3)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 95 32
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memw(r21+r31<<#3) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f1 ff 95 33
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memw(r21+r31<<#3) }
|
||||
# CHECK: b1 da 95 41
|
||||
if (p3) r17 = memw(r21 + #84)
|
||||
# CHECK: b1 da 95 45
|
||||
if (!p3) r17 = memw(r21 + #84)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 da 95 43
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memw(r21 + #84) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 da 95 47
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memw(r21 + #84) }
|
||||
# CHECK: b1 e6 95 9b
|
||||
if (p3) r17 = memw(r21++#20)
|
||||
# CHECK: b1 ee 95 9b
|
||||
if (!p3) r17 = memw(r21++#20)
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 f6 95 9b
|
||||
{ p3 = r5
|
||||
if (p3.new) r17 = memw(r21++#20) }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: b1 fe 95 9b
|
||||
{ p3 = r5
|
||||
if (!p3.new) r17 = memw(r21++#20) }
|
||||
|
||||
# Deallocate stack frame
|
||||
# CHECK: 1e c0 1e 90
|
||||
deallocframe
|
||||
|
||||
# Deallocate stack frame and return
|
||||
# CHECK: 1e c0 1e 96
|
||||
dealloc_return
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1e cb 1e 96
|
||||
{ p3 = r5
|
||||
if (p3.new) dealloc_return:nt }
|
||||
# CHECK: 1e d3 1e 96
|
||||
if (p3) dealloc_return
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1e db 1e 96
|
||||
{ p3 = r5
|
||||
if (p3.new) dealloc_return:t }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1e eb 1e 96
|
||||
{ p3 = r5
|
||||
if (!p3.new) dealloc_return:nt }
|
||||
# CHECK: 1e f3 1e 96
|
||||
if (!p3) dealloc_return
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1e fb 1e 96
|
||||
{ p3 = r5
|
||||
if (!p3.new) dealloc_return:t }
|
||||
|
||||
# Load and unpack bytes to halfwords
|
||||
# CHECK: f1 c3 35 90
|
||||
r17 = membh(r21 + #62)
|
||||
# CHECK: f1 c3 75 90
|
||||
r17 = memubh(r21 + #62)
|
||||
# CHECK: f0 c3 b5 90
|
||||
r17:16 = memubh(r21 + #124)
|
||||
# CHECK: f0 c3 f5 90
|
||||
r17:16 = membh(r21 + #124)
|
||||
# CHECK: b1 e0 35 98
|
||||
r17 = membh(r21 ++ #10:circ(m1))
|
||||
# CHECK: 11 e2 35 98
|
||||
r17 = membh(r21 ++ I:circ(m1))
|
||||
# CHECK: b1 e0 75 98
|
||||
r17 = memubh(r21 ++ #10:circ(m1))
|
||||
# CHECK: 11 e2 75 98
|
||||
r17 = memubh(r21 ++ I:circ(m1))
|
||||
# CHECK: b0 e0 f5 98
|
||||
r17:16 = membh(r21 ++ #20:circ(m1))
|
||||
# CHECK: 10 e2 f5 98
|
||||
r17:16 = membh(r21 ++ I:circ(m1))
|
||||
# CHECK: b0 e0 b5 98
|
||||
r17:16 = memubh(r21 ++ #20:circ(m1))
|
||||
# CHECK: 10 e2 b5 98
|
||||
r17:16 = memubh(r21 ++ I:circ(m1))
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 71 d7 35 9a
|
||||
r17 = membh(r21 = ##31)
|
||||
# CHECK: b1 c0 35 9a
|
||||
r17 = membh(r21++#10)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 71 d7 75 9a
|
||||
r17 = memubh(r21 = ##31)
|
||||
# CHECK: b1 c0 75 9a
|
||||
r17 = memubh(r21++#10)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 70 d7 b5 9a
|
||||
r17:16 = memubh(r21 = ##31)
|
||||
# CHECK: b0 c0 b5 9a
|
||||
r17:16 = memubh(r21++#20)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 70 d7 f5 9a
|
||||
r17:16 = membh(r21 = ##31)
|
||||
# CHECK: b0 c0 f5 9a
|
||||
r17:16 = membh(r21++#20)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: f1 f7 35 9c
|
||||
r17 = membh(r21<<#3 + ##31)
|
||||
# CHECK: 11 e0 35 9c
|
||||
r17 = membh(r21++m1)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: f1 f7 75 9c
|
||||
r17 = memubh(r21<<#3 + ##31)
|
||||
# CHECK: 11 e0 75 9c
|
||||
r17 = memubh(r21++m1)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: f0 f7 f5 9c
|
||||
r17:16 = membh(r21<<#3 + ##31)
|
||||
# CHECK: 10 e0 f5 9c
|
||||
r17:16 = membh(r21++m1)
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: f0 f7 b5 9c
|
||||
r17:16 = memubh(r21<<#3 + ##31)
|
||||
# CHECK: 11 e0 35 9c
|
||||
r17 = membh(r21++m1)
|
||||
# CHECK: 11 e0 75 9c
|
||||
r17 = memubh(r21++m1)
|
||||
# CHECK: 10 e0 f5 9c
|
||||
r17:16 = membh(r21++m1)
|
||||
# CHECK: 10 e0 b5 9c
|
||||
r17:16 = memubh(r21++m1)
|
||||
# CHECK: 11 e0 35 9e
|
||||
r17 = membh(r21 ++ m1:brev)
|
||||
# CHECK: 11 e0 75 9e
|
||||
r17 = memubh(r21 ++ m1:brev)
|
||||
# CHECK: 10 e0 b5 9e
|
||||
r17:16 = memubh(r21 ++ m1:brev)
|
||||
# CHECK: 10 e0 f5 9e
|
||||
r17:16 = membh(r21 ++ m1:brev)
|
56
test/MC/Hexagon/instructions/memop.s
Normal file
56
test/MC/Hexagon/instructions/memop.s
Normal file
@ -0,0 +1,56 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.6 MEMOP
|
||||
|
||||
# Operation on memory byte
|
||||
# CHECK: 95 d9 11 3e
|
||||
memb(r17+#51) += r21
|
||||
# CHECK: b5 d9 11 3e
|
||||
memb(r17+#51) -= r21
|
||||
# CHECK: d5 d9 11 3e
|
||||
memb(r17+#51) &= r21
|
||||
# CHECK: f5 d9 11 3e
|
||||
memb(r17+#51) |= r21
|
||||
# CHECK: 95 d9 11 3f
|
||||
memb(r17+#51) += #21
|
||||
# CHECK: b5 d9 11 3f
|
||||
memb(r17+#51) -= #21
|
||||
# CHECK: d5 d9 11 3f
|
||||
memb(r17+#51) = clrbit(#21)
|
||||
# CHECK: f5 d9 11 3f
|
||||
memb(r17+#51) = setbit(#21)
|
||||
|
||||
# Operation on memory halfword
|
||||
# CHECK: 95 d9 31 3e
|
||||
memh(r17+#102) += r21
|
||||
# CHECK: b5 d9 31 3e
|
||||
memh(r17+#102) -= r21
|
||||
# CHECK: d5 d9 31 3e
|
||||
memh(r17+#102) &= r21
|
||||
# CHECK: f5 d9 31 3e
|
||||
memh(r17+#102) |= r21
|
||||
# CHECK: 95 d9 31 3f
|
||||
memh(r17+#102) += #21
|
||||
# CHECK: b5 d9 31 3f
|
||||
memh(r17+#102) -= #21
|
||||
# CHECK: d5 d9 31 3f
|
||||
memh(r17+#102) = clrbit(#21)
|
||||
# CHECK: f5 d9 31 3f
|
||||
memh(r17+#102) = setbit(#21)
|
||||
|
||||
# Operation on memory word
|
||||
# CHECK: 95 d9 51 3e
|
||||
memw(r17+#204) += r21
|
||||
# CHECK: b5 d9 51 3e
|
||||
memw(r17+#204) -= r21
|
||||
# CHECK: d5 d9 51 3e
|
||||
memw(r17+#204) &= r21
|
||||
# CHECK: f5 d9 51 3e
|
||||
memw(r17+#204) |= r21
|
||||
# CHECK: 95 d9 51 3f
|
||||
memw(r17+#204) += #21
|
||||
# CHECK: b5 d9 51 3f
|
||||
memw(r17+#204) -= #21
|
||||
# CHECK: d5 d9 51 3f
|
||||
memw(r17+#204) = clrbit(#21)
|
||||
# CHECK: f5 d9 51 3f
|
||||
memw(r17+#204) = setbit(#21)
|
180
test/MC/Hexagon/instructions/nv_j.s
Normal file
180
test/MC/Hexagon/instructions/nv_j.s
Normal file
@ -0,0 +1,180 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.7.1 NV/J
|
||||
|
||||
# Jump to address conditioned on new register value
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 02 20
|
||||
{ r17 = r17
|
||||
if (cmp.eq(r17.new, r21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 02 20
|
||||
{ r17 = r17
|
||||
if (cmp.eq(r17.new, r21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 42 20
|
||||
{ r17 = r17
|
||||
if (!cmp.eq(r17.new, r21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 42 20
|
||||
{ r17 = r17
|
||||
if (!cmp.eq(r17.new, r21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 82 20
|
||||
{ r17 = r17
|
||||
if (cmp.gt(r17.new, r21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 82 20
|
||||
{ r17 = r17
|
||||
if (cmp.gt(r17.new, r21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 c2 20
|
||||
{ r17 = r17
|
||||
if (!cmp.gt(r17.new, r21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 c2 20
|
||||
{ r17 = r17
|
||||
if (!cmp.gt(r17.new, r21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 02 21
|
||||
{ r17 = r17
|
||||
if (cmp.gtu(r17.new, r21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 02 21
|
||||
{ r17 = r17
|
||||
if (cmp.gtu(r17.new, r21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 42 21
|
||||
{ r17 = r17
|
||||
if (!cmp.gtu(r17.new, r21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 42 21
|
||||
{ r17 = r17
|
||||
if (!cmp.gtu(r17.new, r21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 82 21
|
||||
{ r17 = r17
|
||||
if (cmp.gt(r21, r17.new)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 82 21
|
||||
{ r17 = r17
|
||||
if (cmp.gt(r21, r17.new)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 c2 21
|
||||
{ r17 = r17
|
||||
if (!cmp.gt(r21, r17.new)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 c2 21
|
||||
{ r17 = r17
|
||||
if (!cmp.gt(r21, r17.new)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 02 22
|
||||
{ r17 = r17
|
||||
if (cmp.gtu(r21, r17.new)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 02 22
|
||||
{ r17 = r17
|
||||
if (cmp.gtu(r21, r17.new)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 42 22
|
||||
{ r17 = r17
|
||||
if (!cmp.gtu(r21, r17.new)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 42 22
|
||||
{ r17 = r17
|
||||
if (!cmp.gtu(r21, r17.new)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 02 24
|
||||
{ r17 = r17
|
||||
if (cmp.eq(r17.new, #21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 02 24
|
||||
{ r17 = r17
|
||||
if (cmp.eq(r17.new, #21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 42 24
|
||||
{ r17 = r17
|
||||
if (!cmp.eq(r17.new, #21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 42 24
|
||||
{ r17 = r17
|
||||
if (!cmp.eq(r17.new, #21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 82 24
|
||||
{ r17 = r17
|
||||
if (cmp.gt(r17.new, #21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 82 24
|
||||
{ r17 = r17
|
||||
if (cmp.gt(r17.new, #21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 c2 24
|
||||
{ r17 = r17
|
||||
if (!cmp.gt(r17.new, #21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 c2 24
|
||||
{ r17 = r17
|
||||
if (!cmp.gt(r17.new, #21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 02 25
|
||||
{ r17 = r17
|
||||
if (cmp.gtu(r17.new, #21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 02 25
|
||||
{ r17 = r17
|
||||
if (cmp.gtu(r17.new, #21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 d5 42 25
|
||||
{ r17 = r17
|
||||
if (!cmp.gtu(r17.new, #21)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 f5 42 25
|
||||
{ r17 = r17
|
||||
if (!cmp.gtu(r17.new, #21)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 c0 82 25
|
||||
{ r17 = r17
|
||||
if (tstbit(r17.new, #0)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 e0 82 25
|
||||
{ r17 = r17
|
||||
if (tstbit(r17.new, #0)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 c0 c2 25
|
||||
{ r17 = r17
|
||||
if (!tstbit(r17.new, #0)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 e0 c2 25
|
||||
{ r17 = r17
|
||||
if (!tstbit(r17.new, #0)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 c0 02 26
|
||||
{ r17 = r17
|
||||
if (cmp.eq(r17.new, #-1)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 e0 02 26
|
||||
{ r17 = r17
|
||||
if (cmp.eq(r17.new, #-1)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 c0 42 26
|
||||
{ r17 = r17
|
||||
if (!cmp.eq(r17.new, #-1)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 e0 42 26
|
||||
{ r17 = r17
|
||||
if (!cmp.eq(r17.new, #-1)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 c0 82 26
|
||||
{ r17 = r17
|
||||
if (cmp.gt(r17.new, #-1)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 e0 82 26
|
||||
{ r17 = r17
|
||||
if (cmp.gt(r17.new, #-1)) jump:t 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 c0 c2 26
|
||||
{ r17 = r17
|
||||
if (!cmp.gt(r17.new, #-1)) jump:nt 0x0 }
|
||||
# CHECK: 11 40 71 70
|
||||
# CHECK-NEXT: 00 e0 c2 26
|
||||
{ r17 = r17
|
||||
if (!cmp.gt(r17.new, #-1)) jump:t 0x0 }
|
290
test/MC/Hexagon/instructions/nv_st.s
Normal file
290
test/MC/Hexagon/instructions/nv_st.s
Normal file
@ -0,0 +1,290 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.7.2 NV/ST
|
||||
|
||||
# Store new-value byte
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 82 f5 b1 3b
|
||||
{ r31 = r31
|
||||
memb(r17 + r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 11 c2 a0 48
|
||||
{ r31 = r31
|
||||
memb(#17) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 15 c2 b1 a1
|
||||
{ r31 = r31
|
||||
memb(r17+#21) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 02 e2 b1 a9
|
||||
{ r31 = r31
|
||||
memb(r17 ++ I:circ(m1)) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 28 e2 b1 a9
|
||||
{ r31 = r31
|
||||
memb(r17 ++ #5:circ(m1)) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 28 c2 b1 ab
|
||||
{ r31 = r31
|
||||
memb(r17++#5) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 00 e2 b1 ad
|
||||
{ r31 = r31
|
||||
memb(r17++m1) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 00 e2 b1 af
|
||||
{ r31 = r31
|
||||
memb(r17 ++ m1:brev) = r31.new }
|
||||
|
||||
# Store new-value byte conditionally
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: e2 f5 b1 34
|
||||
{ r31 = r31
|
||||
if (p3) memb(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: e2 f5 b1 35
|
||||
{ r31 = r31
|
||||
if (!p3) memb(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: e2 f5 b1 36
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memb(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: e2 f5 b1 37
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memb(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab c2 b1 40
|
||||
{ r31 = r31
|
||||
if (p3) memb(r17+#21) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab c2 b1 44
|
||||
{ r31 = r31
|
||||
if (!p3) memb(r17+#21) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab c2 b1 42
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memb(r17+#21) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab c2 b1 46
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memb(r17+#21) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 2b e2 b1 ab
|
||||
{ r31 = r31
|
||||
if (p3) memb(r17++#5) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 2f e2 b1 ab
|
||||
{ r31 = r31
|
||||
if (!p3) memb(r17++#5) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab e2 b1 ab
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memb(r17++#5) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: af e2 b1 ab
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memb(r17++#5) = r31.new }
|
||||
|
||||
# Store new-value halfword
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 8a f5 b1 3b
|
||||
{ r31 = r31
|
||||
memh(r17 + r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 15 ca a0 48
|
||||
{ r31 = r31
|
||||
memh(#42) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 15 ca b1 a1
|
||||
{ r31 = r31
|
||||
memh(r17+#42) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 02 ea b1 a9
|
||||
{ r31 = r31
|
||||
memh(r17 ++ I:circ(m1)) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 28 ea b1 a9
|
||||
{ r31 = r31
|
||||
memh(r17 ++ #10:circ(m1)) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 28 ca b1 ab
|
||||
{ r31 = r31
|
||||
memh(r17++#10) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 00 ea b1 ad
|
||||
{ r31 = r31
|
||||
memh(r17++m1) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 00 ea b1 af
|
||||
{ r31 = r31
|
||||
memh(r17 ++ m1:brev) = r31.new }
|
||||
|
||||
# Store new-value halfword conditionally
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: ea f5 b1 34
|
||||
{ r31 = r31
|
||||
if (p3) memh(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: ea f5 b1 35
|
||||
{ r31 = r31
|
||||
if (!p3) memh(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ea f5 b1 36
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memh(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ea f5 b1 37
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memh(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab ca b1 40
|
||||
{ r31 = r31
|
||||
if (p3) memh(r17+#42) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab ca b1 44
|
||||
{ r31 = r31
|
||||
if (!p3) memh(r17+#42) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab ca b1 42
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memh(r17+#42) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab ca b1 46
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memh(r17+#42) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 2b ea b1 ab
|
||||
{ r31 = r31
|
||||
if (p3) memh(r17++#10) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 2f ea b1 ab
|
||||
{ r31 = r31
|
||||
if (!p3) memh(r17++#10) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab ea b1 ab
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memh(r17++#10) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: af ea b1 ab
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memh(r17++#10) = r31.new }
|
||||
|
||||
# Store new-value word
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 92 f5 b1 3b
|
||||
{ r31 = r31
|
||||
memw(r17 + r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 15 d2 a0 48
|
||||
{ r31 = r31
|
||||
memw(#84) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 15 d2 b1 a1
|
||||
{ r31 = r31
|
||||
memw(r17+#84) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 02 f2 b1 a9
|
||||
{ r31 = r31
|
||||
memw(r17 ++ I:circ(m1)) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 28 f2 b1 a9
|
||||
{ r31 = r31
|
||||
memw(r17 ++ #20:circ(m1)) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 28 d2 b1 ab
|
||||
{ r31 = r31
|
||||
memw(r17++#20) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 00 f2 b1 ad
|
||||
{ r31 = r31
|
||||
memw(r17++m1) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 00 f2 b1 af
|
||||
{ r31 = r31
|
||||
memw(r17 ++ m1:brev) = r31.new }
|
||||
|
||||
# Store new-value word conditionally
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: f2 f5 b1 34
|
||||
{ r31 = r31
|
||||
if (p3) memw(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: f2 f5 b1 35
|
||||
{ r31 = r31
|
||||
if (!p3) memw(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: f2 f5 b1 36
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memw(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: f2 f5 b1 37
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memw(r17+r21<<#3) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab d2 b1 40
|
||||
{ r31 = r31
|
||||
if (p3) memw(r17+#84) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab d2 b1 44
|
||||
{ r31 = r31
|
||||
if (!p3) memw(r17+#84) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab d2 b1 42
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memw(r17+#84) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab d2 b1 46
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memw(r17+#84) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 2b f2 b1 ab
|
||||
{ r31 = r31
|
||||
if (p3) memw(r17++#20) = r31.new }
|
||||
# CHECK: 1f 40 7f 70
|
||||
# CHECK-NEXT: 2f f2 b1 ab
|
||||
{ r31 = r31
|
||||
if (!p3) memw(r17++#20) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: ab f2 b1 ab
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (p3.new) memw(r17++#20) = r31.new }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 1f 40 7f 70
|
||||
# CHECK-NEXT: af f2 b1 ab
|
||||
{ p3 = r5
|
||||
r31 = r31
|
||||
if (!p3.new) memw(r17++#20) = r31.new }
|
435
test/MC/Hexagon/instructions/st.s
Normal file
435
test/MC/Hexagon/instructions/st.s
Normal file
@ -0,0 +1,435 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.8 ST
|
||||
# XFAIL: *
|
||||
|
||||
# Store doubleword
|
||||
# CHECK: 9e f5 d1 3b
|
||||
memd(r17 + r21<<#3) = r31:30
|
||||
# CHECK: 28 d4 c0 48
|
||||
memd(#320) = r21:20
|
||||
# CHECK: 02 40 00 00
|
||||
# CHECK-NEXT: 28 d4 c0 48
|
||||
memd(##168) = r21:20
|
||||
memd(r17+#168) = r21:20
|
||||
# CHECK: 02 f4 d1 a9
|
||||
memd(r17 ++ I:circ(m1)) = r21:20
|
||||
# CHECK: 28 f4 d1 a9
|
||||
memd(r17 ++ #40:circ(m1)) = r21:20
|
||||
# CHECK: 28 d4 d1 ab
|
||||
memd(r17++#40) = r21:20
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d5 fe d1 ad
|
||||
memd(r17<<#3 + ##21) = r31:30
|
||||
memd(r17++m1) = r21:20
|
||||
# CHECK: 00 f4 d1 af
|
||||
memd(r17 ++ m1:brev) = r21:20
|
||||
|
||||
# Store doubleword conditionally
|
||||
# CHECK: fe f5 d1 34
|
||||
if (p3) memd(r17+r21<<#3) = r31:30
|
||||
# CHECK: fe f5 d1 35
|
||||
if (!p3) memd(r17+r21<<#3) = r31:30
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: fe f5 d1 36
|
||||
{ p3 = r5
|
||||
if (p3.new) memd(r17+r21<<#3) = r31:30 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: fe f5 d1 37
|
||||
{ p3 = r5
|
||||
if (!p3.new) memd(r17+r21<<#3) = r31:30 }
|
||||
# CHECK: ab de d1 40
|
||||
if (p3) memd(r17+#168) = r31:30
|
||||
# CHECK: ab de d1 44
|
||||
if (!p3) memd(r17+#168) = r31:30
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab de d1 42
|
||||
{ p3 = r5
|
||||
if (p3.new) memd(r17+#168) = r31:30 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab de d1 46
|
||||
{ p3 = r5
|
||||
if (!p3.new) memd(r17+#168) = r31:30 }
|
||||
# CHECK: 2b f4 d1 ab
|
||||
if (p3) memd(r17++#40) = r21:20
|
||||
# CHECK: 2f f4 d1 ab
|
||||
if (!p3) memd(r17++#40) = r21:20
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab f4 d1 ab
|
||||
{ p3 = r5
|
||||
if (p3.new) memd(r17++#40) = r21:20 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: af f4 d1 ab
|
||||
{ p3 = r5
|
||||
if (!p3.new) memd(r17++#40) = r21:20 }
|
||||
# CHECK: 02 40 00 00
|
||||
# CHECK-NEXT: c3 d4 c2 af
|
||||
if (p3) memd(##168) = r21:20
|
||||
# CHECK: 02 40 00 00
|
||||
# CHECK-NEXT: c7 d4 c2 af
|
||||
if (!p3) memd(##168) = r21:20
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 02 40 00 00
|
||||
# CHECK-NEXT: c3 f4 c2 af
|
||||
{ p3 = r5
|
||||
if (p3.new) memd(##168) = r21:20 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 02 40 00 00
|
||||
# CHECK-NEXT: c7 f4 c2 af
|
||||
{ p3 = r5
|
||||
if (!p3.new) memd(##168) = r21:20 }
|
||||
|
||||
# Store byte
|
||||
# CHECK: 9f f5 11 3b
|
||||
memb(r17 + r21<<#3) = r31
|
||||
# CHECK: 9f ca 11 3c
|
||||
memb(r17+#21)=#31
|
||||
# CHECK: 15 d5 00 48
|
||||
memb(#21) = r21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 15 d5 00 48
|
||||
memb(##21) = r21
|
||||
# CHECK: 15 d5 11 a1
|
||||
memb(r17+#21) = r21
|
||||
# CHECK: 02 f5 11 a9
|
||||
memb(r17 ++ I:circ(m1)) = r21
|
||||
# CHECK: 28 f5 11 a9
|
||||
memb(r17 ++ #5:circ(m1)) = r21
|
||||
# CHECK: 28 d5 11 ab
|
||||
memb(r17++#5) = r21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d5 ff 11 ad
|
||||
memb(r17<<#3 + ##21) = r31
|
||||
# CHECK: 00 f5 11 ad
|
||||
memb(r17++m1) = r21
|
||||
# CHECK: 00 f5 11 af
|
||||
memb(r17 ++ m1:brev) = r21
|
||||
|
||||
# Store byte conditionally
|
||||
# CHECK: ff f5 11 34
|
||||
if (p3) memb(r17+r21<<#3) = r31
|
||||
# CHECK: ff f5 11 35
|
||||
if (!p3) memb(r17+r21<<#3) = r31
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff f5 11 36
|
||||
{ p3 = r5
|
||||
if (p3.new) memb(r17+r21<<#3) = r31 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff f5 11 37
|
||||
{ p3 = r5
|
||||
if (!p3.new) memb(r17+r21<<#3) = r31 }
|
||||
# CHECK: ff ca 11 38
|
||||
if (p3) memb(r17+#21)=#31
|
||||
# CHECK: ff ca 91 38
|
||||
if (!p3) memb(r17+#21)=#31
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff ca 11 39
|
||||
{ p3 = r5
|
||||
if (p3.new) memb(r17+#21)=#31 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff ca 91 39
|
||||
{ p3 = r5
|
||||
if (!p3.new) memb(r17+#21)=#31 }
|
||||
# CHECK: ab df 11 40
|
||||
if (p3) memb(r17+#21) = r31
|
||||
# CHECK: ab df 11 44
|
||||
if (!p3) memb(r17+#21) = r31
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab df 11 42
|
||||
{ p3 = r5
|
||||
if (p3.new) memb(r17+#21) = r31 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab df 11 46
|
||||
{ p3 = r5
|
||||
if (!p3.new) memb(r17+#21) = r31 }
|
||||
# CHECK: 2b f5 11 ab
|
||||
if (p3) memb(r17++#5) = r21
|
||||
# CHECK: 2f f5 11 ab
|
||||
if (!p3) memb(r17++#5) = r21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab f5 11 ab
|
||||
{ p3 = r5
|
||||
if (p3.new) memb(r17++#5) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: af f5 11 ab
|
||||
{ p3 = r5
|
||||
if (!p3.new) memb(r17++#5) = r21 }
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: ab d5 01 af
|
||||
if (p3) memb(##21) = r21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: af d5 01 af
|
||||
if (!p3) memb(##21) = r21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 40 00 00
|
||||
# CHECK-NEXT: ab f5 01 af
|
||||
{ p3 = r5
|
||||
if (p3.new) memb(##21) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 40 00 00
|
||||
# CHECK-NEXT: af f5 01 af
|
||||
{ p3 = r5
|
||||
if (!p3.new) memb(##21) = r21 }
|
||||
|
||||
# Store halfword
|
||||
# CHECK: 9f f5 51 3b
|
||||
memh(r17 + r21<<#3) = r31
|
||||
# CHECK: 9f f5 71 3b
|
||||
memh(r17 + r21<<#3) = r31.h
|
||||
# CHECK: 95 cf 31 3c
|
||||
memh(r17+#62)=#21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 2a d5 40 48
|
||||
memh(##42) = r21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: 2a d5 60 48
|
||||
memh(##42) = r21.h
|
||||
# CHECK: 2a d5 40 48
|
||||
memh(#84) = r21
|
||||
# CHECK: 2a d5 60 48
|
||||
memh(#84) = r21.h
|
||||
# CHECK: 15 df 51 a1
|
||||
memh(r17+#42) = r31
|
||||
# CHECK: 15 df 71 a1
|
||||
memh(r17+#42) = r31.h
|
||||
# CHECK: 02 f5 51 a9
|
||||
memh(r17 ++ I:circ(m1)) = r21
|
||||
# CHECK: 28 f5 51 a9
|
||||
memh(r17 ++ #10:circ(m1)) = r21
|
||||
# CHECK: 02 f5 71 a9
|
||||
memh(r17 ++ I:circ(m1)) = r21.h
|
||||
# CHECK: 28 f5 71 a9
|
||||
memh(r17 ++ #10:circ(m1)) = r21.h
|
||||
# CHECK: 28 d5 51 ab
|
||||
memh(r17++#10) = r21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d5 ff 51 ad
|
||||
memh(r17<<#3 + ##21) = r31
|
||||
# CHECK: 28 d5 71 ab
|
||||
memh(r17++#10) = r21.h
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d5 ff 71 ad
|
||||
memh(r17<<#3 + ##21) = r31.h
|
||||
# CHECK: 00 f5 51 ad
|
||||
memh(r17++m1) = r21
|
||||
# CHECK: 00 f5 71 ad
|
||||
memh(r17++m1) = r21.h
|
||||
# CHECK: 00 f5 51 af
|
||||
memh(r17 ++ m1:brev) = r21
|
||||
# CHECK: 00 f5 71 af
|
||||
memh(r17 ++ m1:brev) = r21.h
|
||||
|
||||
# Store halfword conditionally
|
||||
# CHECK: ff f5 51 34
|
||||
if (p3) memh(r17+r21<<#3) = r31
|
||||
# CHECK: ff f5 71 34
|
||||
if (p3) memh(r17+r21<<#3) = r31.h
|
||||
# CHECK: ff f5 51 35
|
||||
if (!p3) memh(r17+r21<<#3) = r31
|
||||
# CHECK: ff f5 71 35
|
||||
if (!p3) memh(r17+r21<<#3) = r31.h
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff f5 51 36
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(r17+r21<<#3) = r31 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff f5 71 36
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(r17+r21<<#3) = r31.h }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff f5 51 37
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(r17+r21<<#3) = r31 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff f5 71 37
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(r17+r21<<#3) = r31.h }
|
||||
# CHECK: f5 cf 31 38
|
||||
if (p3) memh(r17+#62)=#21
|
||||
# CHECK: f5 cf b1 38
|
||||
if (!p3) memh(r17+#62)=#21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f5 cf 31 39
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(r17+#62)=#21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: f5 cf b1 39
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(r17+#62)=#21 }
|
||||
# CHECK: fb d5 51 40
|
||||
if (p3) memh(r17+#62) = r21
|
||||
# CHECK: fb d5 71 40
|
||||
if (p3) memh(r17+#62) = r21.h
|
||||
# CHECK: fb d5 51 44
|
||||
if (!p3) memh(r17+#62) = r21
|
||||
# CHECK: fb d5 71 44
|
||||
if (!p3) memh(r17+#62) = r21.h
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: fb d5 51 42
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(r17+#62) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: fb d5 71 42
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(r17+#62) = r21.h }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: fb d5 51 46
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(r17+#62) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: fb d5 71 46
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(r17+#62) = r21.h }
|
||||
# CHECK: 2b f5 51 ab
|
||||
if (p3) memh(r17++#10) = r21
|
||||
# CHECK: 2f f5 51 ab
|
||||
if (!p3) memh(r17++#10) = r21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab f5 51 ab
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(r17++#10) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: af f5 51 ab
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(r17++#10) = r21 }
|
||||
# CHECK: 2b f5 71 ab
|
||||
if (p3) memh(r17++#10) = r21.h
|
||||
# CHECK: 2f f5 71 ab
|
||||
if (!p3) memh(r17++#10) = r21.h
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab f5 71 ab
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(r17++#10) = r21.h }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: af f5 71 ab
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(r17++#10) = r21.h }
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d3 d5 42 af
|
||||
if (p3) memh(##42) = r21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d3 d5 62 af
|
||||
if (p3) memh(##42) = r21.h
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d7 d5 42 af
|
||||
if (!p3) memh(##42) = r21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d7 d5 62 af
|
||||
if (!p3) memh(##42) = r21.h
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 40 00 00
|
||||
# CHECK-NEXT: d3 f5 42 af
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(##42) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 40 00 00
|
||||
# CHECK-NEXT: d3 f5 62 af
|
||||
{ p3 = r5
|
||||
if (p3.new) memh(##42) = r21.h }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 40 00 00
|
||||
# CHECK-NEXT: d7 f5 42 af
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(##42) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 00 40 00 00
|
||||
# CHECK-NEXT: d7 f5 62 af
|
||||
{ p3 = r5
|
||||
if (!p3.new) memh(##42) = r21.h }
|
||||
|
||||
# Store word
|
||||
# CHECK: 9f f5 91 3b
|
||||
memw(r17 + r21<<#3) = r31
|
||||
# CHECK: 9f ca 51 3c
|
||||
memw(r17+#84)=#31
|
||||
# CHECK: 15 df 80 48
|
||||
memw(#84) = r31
|
||||
# CHECK: 01 40 00 00
|
||||
# CHECK-NEXT: 14 d5 80 48
|
||||
memw(##84) = r21
|
||||
# CHECK: 9f ca 51 3c
|
||||
memw(r17+#84)=#31
|
||||
# CHECK: 15 df 91 a1
|
||||
memw(r17+#84) = r31
|
||||
# CHECK: 02 f5 91 a9
|
||||
memw(r17 ++ I:circ(m1)) = r21
|
||||
# CHECK: 28 f5 91 a9
|
||||
memw(r17 ++ #20:circ(m1)) = r21
|
||||
# CHECK: 28 d5 91 ab
|
||||
memw(r17++#20) = r21
|
||||
# CHECK: 00 40 00 00
|
||||
# CHECK-NEXT: d5 ff 91 ad
|
||||
memw(r17<<#3 + ##21) = r31
|
||||
# CHECK: 00 f5 91 ad
|
||||
memw(r17++m1) = r21
|
||||
# CHECK: 00 f5 91 af
|
||||
memw(r17 ++ m1:brev) = r21
|
||||
|
||||
# Store word conditionally
|
||||
# CHECK: ff f5 91 34
|
||||
if (p3) memw(r17+r21<<#3) = r31
|
||||
# CHECK: ff f5 91 35
|
||||
if (!p3) memw(r17+r21<<#3) = r31
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff f5 91 36
|
||||
{ p3 = r5
|
||||
if (p3.new) memw(r17+r21<<#3) = r31 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff f5 91 37
|
||||
{ p3 = r5
|
||||
if (!p3.new) memw(r17+r21<<#3) = r31 }
|
||||
# CHECK: ff ca 51 38
|
||||
if (p3) memw(r17+#84)=#31
|
||||
# CHECK: ff ca d1 38
|
||||
if (!p3) memw(r17+#84)=#31
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff ca 51 39
|
||||
{ p3 = r5
|
||||
if (p3.new) memw(r17+#84)=#31 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ff ca d1 39
|
||||
{ p3 = r5
|
||||
if (!p3.new) memw(r17+#84)=#31 }
|
||||
# CHECK: ab df 91 40
|
||||
if (p3) memw(r17+#84) = r31
|
||||
# CHECK: ab df 91 44
|
||||
if (!p3) memw(r17+#84) = r31
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab df 91 42
|
||||
{ p3 = r5
|
||||
if (p3.new) memw(r17+#84) = r31 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab df 91 46
|
||||
{ p3 = r5
|
||||
if (!p3.new) memw(r17+#84) = r31 }
|
||||
# CHECK: 2b f5 91 ab
|
||||
if (p3) memw(r17++#20) = r21
|
||||
# CHECK: 2f f5 91 ab
|
||||
if (!p3) memw(r17++#20) = r21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: af f5 91 ab
|
||||
{ p3 = r5
|
||||
if (!p3.new) memw(r17++#20) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: ab f5 91 ab
|
||||
{ p3 = r5
|
||||
if (p3.new) memw(r17++#20) = r21 }
|
||||
# CHECK: 01 40 00 00
|
||||
# CHECK-NEXT: a3 d5 81 af
|
||||
if (p3) memw(##84) = r21
|
||||
# CHECK: 01 40 00 00
|
||||
# CHECK-NEXT: a7 d5 81 af
|
||||
if (!p3) memw(##84) = r21
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 01 40 00 00
|
||||
# CHECK-NEXT: a3 f5 81 af
|
||||
{ p3 = r5
|
||||
if (p3.new) memw(##84) = r21 }
|
||||
# CHECK: 03 40 45 85
|
||||
# CHECK-NEXT: 01 40 00 00
|
||||
# CHECK-NEXT: a7 f5 81 af
|
||||
{ p3 = r5
|
||||
if (!p3.new) memw(##84) = r21 }
|
||||
|
||||
# Allocate stack frame
|
||||
# CHECK: 1f c0 9d a0
|
||||
allocframe(#248)
|
26
test/MC/Hexagon/instructions/system_user.s
Normal file
26
test/MC/Hexagon/instructions/system_user.s
Normal file
@ -0,0 +1,26 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.9.1 SYSTEM/USER
|
||||
|
||||
# Load locked
|
||||
# CHECK: 11 c0 15 92
|
||||
r17 = memw_locked(r21)
|
||||
# CHECK: 10 d0 15 92
|
||||
r17:16 = memd_locked(r21)
|
||||
|
||||
# Store conditional
|
||||
# CHECK: 03 d5 b1 a0
|
||||
memw_locked(r17, p3) = r21
|
||||
# CHECK: 03 d4 f1 a0
|
||||
memd_locked(r17, p3) = r21:20
|
||||
|
||||
# Memory barrier
|
||||
# CHECK: 00 c0 00 a8
|
||||
barrier
|
||||
|
||||
# Data cache prefetch
|
||||
# CHECK: 15 c0 11 94
|
||||
dcfetch(r17 + #168)
|
||||
|
||||
# Send value to ETM trace
|
||||
# CHECK: 00 c0 51 62
|
||||
trace(r17)
|
395
test/MC/Hexagon/instructions/xtype_alu.s
Normal file
395
test/MC/Hexagon/instructions/xtype_alu.s
Normal file
@ -0,0 +1,395 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.10.1 XTYPE/ALU
|
||||
|
||||
# Absolute value doubleword
|
||||
# CHECK: d0 c0 94 80
|
||||
r17:16 = abs(r21:20)
|
||||
# CHECK: 91 c0 95 8c
|
||||
r17 = abs(r21)
|
||||
# CHECK: b1 c0 95 8c
|
||||
r17 = abs(r21):sat
|
||||
|
||||
# Add and accumulate
|
||||
# CHECK: ff d1 35 db
|
||||
r17 = add(r21, add(r31, #23))
|
||||
# CHECK: ff d1 b5 db
|
||||
r17 = add(r21, sub(#23, r31))
|
||||
# CHECK: f1 c2 15 e2
|
||||
r17 += add(r21, #23)
|
||||
# CHECK: f1 c2 95 e2
|
||||
r17 -= add(r21, #23)
|
||||
# CHECK: 31 df 15 ef
|
||||
r17 += add(r21, r31)
|
||||
# CHECK: 31 df 95 ef
|
||||
r17 -= add(r21, r31)
|
||||
|
||||
# Add doublewords
|
||||
# CHECK: f0 de 14 d3
|
||||
r17:16 = add(r21:20, r31:30)
|
||||
# CHECK: b0 de 74 d3
|
||||
r17:16 = add(r21:20, r31:30):sat
|
||||
# CHECK: d0 de 74 d3
|
||||
r17:16 = add(r21:20, r31:30):raw:lo
|
||||
# CHECK: f0 de 74 d3
|
||||
r17:16 = add(r21:20, r31:30):raw:hi
|
||||
|
||||
# Add halfword
|
||||
# CHECK: 11 d5 1f d5
|
||||
r17 = add(r21.l, r31.l)
|
||||
# CHECK: 51 d5 1f d5
|
||||
r17 = add(r21.l, r31.h)
|
||||
# CHECK: 91 d5 1f d5
|
||||
r17 = add(r21.l, r31.l):sat
|
||||
# CHECK: d1 d5 1f d5
|
||||
r17 = add(r21.l, r31.h):sat
|
||||
# CHECK: 11 d5 5f d5
|
||||
r17 = add(r21.l, r31.l):<<16
|
||||
# CHECK: 31 d5 5f d5
|
||||
r17 = add(r21.l, r31.h):<<16
|
||||
# CHECK: 51 d5 5f d5
|
||||
r17 = add(r21.h, r31.l):<<16
|
||||
# CHECK: 71 d5 5f d5
|
||||
r17 = add(r21.h, r31.h):<<16
|
||||
# CHECK: 91 d5 5f d5
|
||||
r17 = add(r21.l, r31.l):sat:<<16
|
||||
# CHECK: b1 d5 5f d5
|
||||
r17 = add(r21.l, r31.h):sat:<<16
|
||||
# CHECK: d1 d5 5f d5
|
||||
r17 = add(r21.h, r31.l):sat:<<16
|
||||
# CHECK: f1 d5 5f d5
|
||||
r17 = add(r21.h, r31.h):sat:<<16
|
||||
|
||||
# Add or subtract doublewords with carry
|
||||
# CHECK: 70 de d4 c2
|
||||
r17:16 = add(r21:20, r31:30, p3):carry
|
||||
# CHECK: 70 de f4 c2
|
||||
r17:16 = sub(r21:20, r31:30, p3):carry
|
||||
|
||||
# Logical doublewords
|
||||
# CHECK: 90 c0 94 80
|
||||
r17:16 = not(r21:20)
|
||||
# CHECK: 10 de f4 d3
|
||||
r17:16 = and(r21:20, r31:30)
|
||||
# CHECK: 30 d4 fe d3
|
||||
r17:16 = and(r21:20, ~r31:30)
|
||||
# CHECK: 50 de f4 d3
|
||||
r17:16 = or(r21:20, r31:30)
|
||||
# CHECK: 70 d4 fe d3
|
||||
r17:16 = or(r21:20, ~r31:30)
|
||||
# CHECK: 90 de f4 d3
|
||||
r17:16 = xor(r21:20, r31:30)
|
||||
|
||||
# Logical-logical doublewords
|
||||
# CHECK: 10 de 94 ca
|
||||
r17:16 ^= xor(r21:20, r31:30)
|
||||
|
||||
# Logical-logical words
|
||||
# CHECK: f1 c3 15 da
|
||||
r17 |= and(r21, #31)
|
||||
# CHECK: f5 c3 51 da
|
||||
r17 = or(r21, and(r17, #31))
|
||||
# CHECK: f1 c3 95 da
|
||||
r17 |= or(r21, #31)
|
||||
# CHECK: 11 df 35 ef
|
||||
r17 |= and(r21, ~r31)
|
||||
# CHECK: 31 df 35 ef
|
||||
r17 &= and(r21, ~r31)
|
||||
# CHECK: 51 df 35 ef
|
||||
r17 ^= and(r21, ~r31)
|
||||
# CHECK: 11 df 55 ef
|
||||
r17 &= and(r21, r31)
|
||||
# CHECK: 31 df 55 ef
|
||||
r17 &= or(r21, r31)
|
||||
# CHECK: 51 df 55 ef
|
||||
r17 &= xor(r21, r31)
|
||||
# CHECK: 71 df 55 ef
|
||||
r17 |= and(r21, r31)
|
||||
# CHECK: 71 df 95 ef
|
||||
r17 ^= xor(r21, r31)
|
||||
# CHECK: 11 df d5 ef
|
||||
r17 |= or(r21, r31)
|
||||
# CHECK: 31 df d5 ef
|
||||
r17 |= xor(r21, r31)
|
||||
# CHECK: 51 df d5 ef
|
||||
r17 ^= and(r21, r31)
|
||||
# CHECK: 71 df d5 ef
|
||||
r17 ^= or(r21, r31)
|
||||
|
||||
# Maximum words
|
||||
# CHECK: 11 df d5 d5
|
||||
r17 = max(r21, r31)
|
||||
# CHECK: 91 df d5 d5
|
||||
r17 = maxu(r21, r31)
|
||||
|
||||
# Maximum doublewords
|
||||
# CHECK: 90 de d4 d3
|
||||
r17:16 = max(r21:20, r31:30)
|
||||
# CHECK: b0 de d4 d3
|
||||
r17:16 = maxu(r21:20, r31:30)
|
||||
|
||||
# Minimum words
|
||||
# CHECK: 11 d5 bf d5
|
||||
r17 = min(r21, r31)
|
||||
# CHECK: 91 d5 bf d5
|
||||
r17 = minu(r21, r31)
|
||||
|
||||
# Minimum doublewords
|
||||
# CHECK: d0 d4 be d3
|
||||
r17:16 = min(r21:20, r31:30)
|
||||
# CHECK: f0 d4 be d3
|
||||
r17:16 = minu(r21:20, r31:30)
|
||||
|
||||
# Module wrap
|
||||
# CHECK: f1 df f5 d3
|
||||
r17 = modwrap(r21, r31)
|
||||
|
||||
# Negate
|
||||
# CHECK: b0 c0 94 80
|
||||
r17:16 = neg(r21:20)
|
||||
# CHECK: d1 c0 95 8c
|
||||
r17 = neg(r21):sat
|
||||
|
||||
# Round
|
||||
# CHECK: 31 c0 d4 88
|
||||
r17 = round(r21:20):sat
|
||||
# CHECK: 11 df f5 8c
|
||||
r17 = cround(r21, #31)
|
||||
# CHECK: 91 df f5 8c
|
||||
r17 = round(r21, #31)
|
||||
# CHECK: d1 df f5 8c
|
||||
r17 = round(r21, #31):sat
|
||||
# CHECK: 11 df d5 c6
|
||||
r17 = cround(r21, r31)
|
||||
# CHECK: 91 df d5 c6
|
||||
r17 = round(r21, r31)
|
||||
# CHECK: d1 df d5 c6
|
||||
r17 = round(r21, r31):sat
|
||||
|
||||
# Subtract doublewords
|
||||
# CHECK: f0 d4 3e d3
|
||||
r17:16 = sub(r21:20, r31:30)
|
||||
|
||||
# Subtract and accumulate words
|
||||
# CHECK: 71 d5 1f ef
|
||||
r17 += sub(r21, r31)
|
||||
|
||||
# Subtract halfword
|
||||
# CHECK: 11 d5 3f d5
|
||||
r17 = sub(r21.l, r31.l)
|
||||
# CHECK: 51 d5 3f d5
|
||||
r17 = sub(r21.l, r31.h)
|
||||
# CHECK: 91 d5 3f d5
|
||||
r17 = sub(r21.l, r31.l):sat
|
||||
# CHECK: d1 d5 3f d5
|
||||
r17 = sub(r21.l, r31.h):sat
|
||||
# CHECK: 11 d5 7f d5
|
||||
r17 = sub(r21.l, r31.l):<<16
|
||||
# CHECK: 31 d5 7f d5
|
||||
r17 = sub(r21.l, r31.h):<<16
|
||||
# CHECK: 51 d5 7f d5
|
||||
r17 = sub(r21.h, r31.l):<<16
|
||||
# CHECK: 71 d5 7f d5
|
||||
r17 = sub(r21.h, r31.h):<<16
|
||||
# CHECK: 91 d5 7f d5
|
||||
r17 = sub(r21.l, r31.l):sat:<<16
|
||||
# CHECK: b1 d5 7f d5
|
||||
r17 = sub(r21.l, r31.h):sat:<<16
|
||||
# CHECK: d1 d5 7f d5
|
||||
r17 = sub(r21.h, r31.l):sat:<<16
|
||||
# CHECK: f1 d5 7f d5
|
||||
r17 = sub(r21.h, r31.h):sat:<<16
|
||||
|
||||
# Sign extend word to doubleword
|
||||
# CHECK: 10 c0 55 84
|
||||
r17:16 = sxtw(r21)
|
||||
|
||||
# Vector absolute value halfwords
|
||||
# CHECK: 90 c0 54 80
|
||||
r17:16 = vabsh(r21:20)
|
||||
# CHECK: b0 c0 54 80
|
||||
r17:16 = vabsh(r21:20):sat
|
||||
|
||||
# Vector absolute value words
|
||||
# CHECK: d0 c0 54 80
|
||||
r17:16 = vabsw(r21:20)
|
||||
# CHECK: f0 c0 54 80
|
||||
r17:16 = vabsw(r21:20):sat
|
||||
|
||||
# Vector absolute difference halfwords
|
||||
# CHECK: 10 d4 7e e8
|
||||
r17:16 = vabsdiffh(r21:20, r31:30)
|
||||
|
||||
# Vector absolute difference words
|
||||
# CHECK: 10 d4 3e e8
|
||||
r17:16 = vabsdiffw(r21:20, r31:30)
|
||||
|
||||
# Vector add halfwords
|
||||
# CHECK: 50 de 14 d3
|
||||
r17:16 = vaddh(r21:20, r31:30)
|
||||
# CHECK: 70 de 14 d3
|
||||
r17:16 = vaddh(r21:20, r31:30):sat
|
||||
# CHECK: 90 de 14 d3
|
||||
r17:16 = vadduh(r21:20, r31:30):sat
|
||||
|
||||
# Vector add halfwords with saturate and pack to unsigned bytes
|
||||
# CHECK: 31 de 54 c1
|
||||
r17 = vaddhub(r21:20, r31:30):sat
|
||||
|
||||
# Vector reduce add unsigned bytes
|
||||
# CHECK: 30 de 54 e8
|
||||
r17:16 = vraddub(r21:20, r31:30)
|
||||
# CHECK: 30 de 54 ea
|
||||
r17:16 += vraddub(r21:20, r31:30)
|
||||
|
||||
# Vector reduce add halfwords
|
||||
# CHECK: 31 de 14 e9
|
||||
r17 = vradduh(r21:20, r31:30)
|
||||
# CHECK: f1 de 34 e9
|
||||
r17 = vraddh(r21:20, r31:30)
|
||||
|
||||
# Vector add bytes
|
||||
# CHECK: 10 de 14 d3
|
||||
r17:16 = vaddub(r21:20, r31:30)
|
||||
# CHECK: 30 de 14 d3
|
||||
r17:16 = vaddub(r21:20, r31:30):sat
|
||||
|
||||
# Vector add words
|
||||
# CHECK: b0 de 14 d3
|
||||
r17:16 = vaddw(r21:20, r31:30)
|
||||
# CHECK: d0 de 14 d3
|
||||
r17:16 = vaddw(r21:20, r31:30):sat
|
||||
|
||||
# Vector average halfwords
|
||||
# CHECK: 50 de 54 d3
|
||||
r17:16 = vavgh(r21:20, r31:30)
|
||||
# CHECK: 70 de 54 d3
|
||||
r17:16 = vavgh(r21:20, r31:30):rnd
|
||||
# CHECK: 90 de 54 d3
|
||||
r17:16 = vavgh(r21:20, r31:30):crnd
|
||||
# CHECK: b0 de 54 d3
|
||||
r17:16 = vavguh(r21:20, r31:30)
|
||||
# CHECK: d0 de 54 d3
|
||||
r17:16 = vavguh(r21:20, r31:30):rnd
|
||||
# CHECK: 10 d4 9e d3
|
||||
r17:16 = vnavgh(r21:20, r31:30)
|
||||
# CHECK: 30 d4 9e d3
|
||||
r17:16 = vnavgh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: 50 d4 9e d3
|
||||
r17:16 = vnavgh(r21:20, r31:30):crnd:sat
|
||||
|
||||
# Vector average unsigned bytes
|
||||
# CHECK: 10 de 54 d3
|
||||
r17:16 = vavgub(r21:20, r31:30)
|
||||
# CHECK: 30 de 54 d3
|
||||
r17:16 = vavgub(r21:20, r31:30):rnd
|
||||
|
||||
# Vector average words
|
||||
# CHECK: 10 de 74 d3
|
||||
r17:16 = vavgw(r21:20, r31:30)
|
||||
# CHECK: 30 de 74 d3
|
||||
r17:16 = vavgw(r21:20, r31:30):rnd
|
||||
# CHECK: 50 de 74 d3
|
||||
r17:16 = vavgw(r21:20, r31:30):crnd
|
||||
# CHECK: 70 de 74 d3
|
||||
r17:16 = vavguw(r21:20, r31:30)
|
||||
# CHECK: 90 de 74 d3
|
||||
r17:16 = vavguw(r21:20, r31:30):rnd
|
||||
# CHECK: 70 d4 9e d3
|
||||
r17:16 = vnavgw(r21:20, r31:30)
|
||||
# CHECK: 90 d4 9e d3
|
||||
r17:16 = vnavgw(r21:20, r31:30):rnd:sat
|
||||
# CHECK: d0 d4 9e d3
|
||||
r17:16 = vnavgw(r21:20, r31:30):crnd:sat
|
||||
|
||||
# Vector conditional negate
|
||||
# CHECK: 50 df d4 c3
|
||||
r17:16 = vcnegh(r21:20, r31)
|
||||
|
||||
# CHECK: f0 ff 34 cb
|
||||
r17:16 += vrcnegh(r21:20, r31)
|
||||
|
||||
# Vector maximum bytes
|
||||
# CHECK: 10 d4 de d3
|
||||
r17:16 = vmaxub(r21:20, r31:30)
|
||||
# CHECK: d0 d4 de d3
|
||||
r17:16 = vmaxb(r21:20, r31:30)
|
||||
|
||||
# Vector maximum halfwords
|
||||
# CHECK: 30 d4 de d3
|
||||
r17:16 = vmaxh(r21:20, r31:30)
|
||||
# CHECK: 50 d4 de d3
|
||||
r17:16 = vmaxuh(r21:20, r31:30)
|
||||
|
||||
# Vector reduce maximum halfwords
|
||||
# CHECK: 3f d0 34 cb
|
||||
r17:16 = vrmaxh(r21:20, r31)
|
||||
# CHECK: 3f f0 34 cb
|
||||
r17:16 = vrmaxuh(r21:20, r31)
|
||||
|
||||
# Vector reduce maximum words
|
||||
# CHECK: 5f d0 34 cb
|
||||
r17:16 = vrmaxw(r21:20, r31)
|
||||
# CHECK: 5f f0 34 cb
|
||||
r17:16 = vrmaxuw(r21:20, r31)
|
||||
|
||||
# Vector maximum words
|
||||
# CHECK: b0 d4 be d3
|
||||
r17:16 = vmaxuw(r21:20, r31:30)
|
||||
# CHECK: 70 d4 de d3
|
||||
r17:16 = vmaxw(r21:20, r31:30)
|
||||
|
||||
# Vector minimum bytes
|
||||
# CHECK: 10 d4 be d3
|
||||
r17:16 = vminub(r21:20, r31:30)
|
||||
# CHECK: f0 d4 de d3
|
||||
r17:16 = vminb(r21:20, r31:30)
|
||||
|
||||
# Vector minimum halfwords
|
||||
# CHECK: 30 d4 be d3
|
||||
r17:16 = vminh(r21:20, r31:30)
|
||||
# CHECK: 50 d4 be d3
|
||||
r17:16 = vminuh(r21:20, r31:30)
|
||||
|
||||
# Vector reduce minimum halfwords
|
||||
# CHECK: bf d0 34 cb
|
||||
r17:16 = vrminh(r21:20, r31)
|
||||
# CHECK: bf f0 34 cb
|
||||
r17:16 = vrminuh(r21:20, r31)
|
||||
|
||||
# Vector reduce minimum words
|
||||
# CHECK: df d0 34 cb
|
||||
r17:16 = vrminw(r21:20, r31)
|
||||
# CHECK: df f0 34 cb
|
||||
r17:16 = vrminuw(r21:20, r31)
|
||||
|
||||
# Vector minimum words
|
||||
# CHECK: 70 d4 be d3
|
||||
r17:16 = vminw(r21:20, r31:30)
|
||||
# CHECK: 90 d4 be d3
|
||||
r17:16 = vminuw(r21:20, r31:30)
|
||||
|
||||
# Vector sum of absolute differences unsigned bytes
|
||||
# CHECK: 50 de 54 e8
|
||||
r17:16 = vrsadub(r21:20, r31:30)
|
||||
# CHECK: 50 de 54 ea
|
||||
r17:16 += vrsadub(r21:20, r31:30)
|
||||
|
||||
# Vector subtract halfwords
|
||||
# CHECK: 50 d4 3e d3
|
||||
r17:16 = vsubh(r21:20, r31:30)
|
||||
# CHECK: 70 d4 3e d3
|
||||
r17:16 = vsubh(r21:20, r31:30):sat
|
||||
# CHECK: 90 d4 3e d3
|
||||
r17:16 = vsubuh(r21:20, r31:30):sat
|
||||
|
||||
# Vector subtract bytes
|
||||
# CHECK: 10 d4 3e d3
|
||||
r17:16 = vsubub(r21:20, r31:30)
|
||||
# CHECK: 30 d4 3e d3
|
||||
r17:16 = vsubub(r21:20, r31:30):sat
|
||||
|
||||
# Vector subtract words
|
||||
# CHECK: b0 d4 3e d3
|
||||
r17:16 = vsubw(r21:20, r31:30)
|
||||
# CHECK: d0 d4 3e d3
|
||||
r17:16 = vsubw(r21:20, r31:30):sat
|
118
test/MC/Hexagon/instructions/xtype_bit.s
Normal file
118
test/MC/Hexagon/instructions/xtype_bit.s
Normal file
@ -0,0 +1,118 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.10.2 XTYPE/BIT
|
||||
|
||||
# Count leading
|
||||
# CHECK: 11 c0 54 88
|
||||
r17 = clb(r21:20)
|
||||
# CHECK: 51 c0 54 88
|
||||
r17 = cl0(r21:20)
|
||||
# CHECK: 91 c0 54 88
|
||||
r17 = cl1(r21:20)
|
||||
# CHECK: 11 c0 74 88
|
||||
r17 = normamt(r21:20)
|
||||
# CHECK: 51 d7 74 88
|
||||
r17 = add(clb(r21:20), #23)
|
||||
# CHECK: 11 d7 35 8c
|
||||
r17 = add(clb(r21), #23)
|
||||
# CHECK: 91 c0 15 8c
|
||||
r17 = clb(r21)
|
||||
# CHECK: b1 c0 15 8c
|
||||
r17 = cl0(r21)
|
||||
# CHECK: d1 c0 15 8c
|
||||
r17 = cl1(r21)
|
||||
# CHECK: f1 c0 15 8c
|
||||
r17 = normamt(r21)
|
||||
|
||||
# Count population
|
||||
# CHECK: 71 c0 74 88
|
||||
r17 = popcount(r21:20)
|
||||
|
||||
# Count trailing
|
||||
# CHECK: 51 c0 f4 88
|
||||
r17 = ct0(r21:20)
|
||||
# CHECK: 91 c0 f4 88
|
||||
r17 = ct1(r21:20)
|
||||
# CHECK: 91 c0 55 8c
|
||||
r17 = ct0(r21)
|
||||
# CHECK: b1 c0 55 8c
|
||||
r17 = ct1(r21)
|
||||
|
||||
# Extract bitfield
|
||||
# CHECK: f0 df 54 81
|
||||
r17:16 = extractu(r21:20, #31, #23)
|
||||
# CHECK: f0 df 54 8a
|
||||
r17:16 = extract(r21:20, #31, #23)
|
||||
# CHECK: f1 df 55 8d
|
||||
r17 = extractu(r21, #31, #23)
|
||||
# CHECK: f1 df d5 8d
|
||||
r17 = extract(r21, #31, #23)
|
||||
# CHECK: 10 de 14 c1
|
||||
r17:16 = extractu(r21:20, r31:30)
|
||||
# CHECK: 90 de d4 c1
|
||||
r17:16 = extract(r21:20, r31:30)
|
||||
# CHECK: 11 de 15 c9
|
||||
r17 = extractu(r21, r31:30)
|
||||
# CHECK: 51 de 15 c9
|
||||
r17 = extract(r21, r31:30)
|
||||
|
||||
# Insert bitfield
|
||||
# CHECK: f0 df 54 83
|
||||
r17:16 = insert(r21:20, #31, #23)
|
||||
# CHECK: f1 df 55 8f
|
||||
r17 = insert(r21, #31, #23)
|
||||
# CHECK: 11 de 15 c8
|
||||
r17 = insert(r21, r31:30)
|
||||
# CHECK: 10 de 14 ca
|
||||
r17:16 = insert(r21:20, r31:30)
|
||||
|
||||
# Interleave/deinterleave
|
||||
# CHECK: 90 c0 d4 80
|
||||
r17:16 = deinterleave(r21:20)
|
||||
# CHECK: b0 c0 d4 80
|
||||
r17:16 = interleave(r21:20)
|
||||
|
||||
# Linear feedback-shift iteration
|
||||
# CHECK: d0 de 94 c1
|
||||
r17:16 = lfs(r21:20, r31:30)
|
||||
|
||||
# Masked parity
|
||||
# CHECK: 11 de 14 d0
|
||||
r17 = parity(r21:20, r31:30)
|
||||
# CHECK: 11 df f5 d5
|
||||
r17 = parity(r21, r31)
|
||||
|
||||
# Bit reverse
|
||||
# CHECK: d0 c0 d4 80
|
||||
r17:16 = brev(r21:20)
|
||||
# CHECK: d1 c0 55 8c
|
||||
r17 = brev(r21)
|
||||
|
||||
# Set/clear/toggle bit
|
||||
# CHECK: 11 df d5 8c
|
||||
r17 = setbit(r21, #31)
|
||||
# CHECK: 31 df d5 8c
|
||||
r17 = clrbit(r21, #31)
|
||||
# CHECK: 51 df d5 8c
|
||||
r17 = togglebit(r21, #31)
|
||||
# CHECK: 11 df 95 c6
|
||||
r17 = setbit(r21, r31)
|
||||
# CHECK: 51 df 95 c6
|
||||
r17 = clrbit(r21, r31)
|
||||
# CHECK: 91 df 95 c6
|
||||
r17 = togglebit(r21, r31)
|
||||
|
||||
# Split bitfield
|
||||
# CHECK: 90 df d5 88
|
||||
r17:16 = bitsplit(r21, #31)
|
||||
# CHECK: 10 df 35 d4
|
||||
r17:16 = bitsplit(r21, r31)
|
||||
|
||||
# Table index
|
||||
# CHECK: f1 cd 15 87
|
||||
r17 = tableidxb(r21, #7, #13):raw
|
||||
# CHECK: f1 cd 55 87
|
||||
r17 = tableidxh(r21, #7, #13):raw
|
||||
# CHECK: f1 cd 95 87
|
||||
r17 = tableidxw(r21, #7, #13):raw
|
||||
# CHECK: f1 cd d5 87
|
||||
r17 = tableidxd(r21, #7, #13):raw
|
128
test/MC/Hexagon/instructions/xtype_complex.s
Normal file
128
test/MC/Hexagon/instructions/xtype_complex.s
Normal file
@ -0,0 +1,128 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.10.3 XTYPE/COMPLEX
|
||||
|
||||
# Complex add/sub halfwords
|
||||
# CHECK: 90 de 54 c1
|
||||
r17:16 = vxaddsubh(r21:20, r31:30):sat
|
||||
# CHECK: d0 de 54 c1
|
||||
r17:16 = vxsubaddh(r21:20, r31:30):sat
|
||||
# CHECK: 10 de d4 c1
|
||||
r17:16 = vxaddsubh(r21:20, r31:30):rnd:>>1:sat
|
||||
# CHECK: 50 de d4 c1
|
||||
r17:16 = vxsubaddh(r21:20, r31:30):rnd:>>1:sat
|
||||
|
||||
# Complex add/sub words
|
||||
# CHECK: 10 de 54 c1
|
||||
r17:16 = vxaddsubw(r21:20, r31:30):sat
|
||||
# CHECK: 50 de 54 c1
|
||||
r17:16 = vxsubaddw(r21:20, r31:30):sat
|
||||
|
||||
# Complex multiply
|
||||
# CHECK: d0 df 15 e5
|
||||
r17:16 = cmpy(r21, r31):sat
|
||||
# CHECK: d0 df 95 e5
|
||||
r17:16 = cmpy(r21, r31):<<1:sat
|
||||
# CHECK: d0 df 55 e5
|
||||
r17:16 = cmpy(r21, r31*):sat
|
||||
# CHECK: d0 df d5 e5
|
||||
r17:16 = cmpy(r21, r31*):<<1:sat
|
||||
# CHECK: d0 df 15 e7
|
||||
r17:16 += cmpy(r21, r31):sat
|
||||
# CHECK: d0 df 95 e7
|
||||
r17:16 += cmpy(r21, r31):<<1:sat
|
||||
# CHECK: f0 df 15 e7
|
||||
r17:16 -= cmpy(r21, r31):sat
|
||||
# CHECK: f0 df 95 e7
|
||||
r17:16 -= cmpy(r21, r31):<<1:sat
|
||||
# CHECK: d0 df 55 e7
|
||||
r17:16 += cmpy(r21, r31*):sat
|
||||
# CHECK: d0 df d5 e7
|
||||
r17:16 += cmpy(r21, r31*):<<1:sat
|
||||
# CHECK: f0 df 55 e7
|
||||
r17:16 -= cmpy(r21, r31*):sat
|
||||
# CHECK: f0 df d5 e7
|
||||
r17:16 -= cmpy(r21, r31*):<<1:sat
|
||||
|
||||
# Complex multiply real or imaginary
|
||||
# CHECK: 30 df 15 e5
|
||||
r17:16 = cmpyi(r21, r31)
|
||||
# CHECK: 50 df 15 e5
|
||||
r17:16 = cmpyr(r21, r31)
|
||||
# CHECK: 30 df 15 e7
|
||||
r17:16 += cmpyi(r21, r31)
|
||||
# CHECK: 50 df 15 e7
|
||||
r17:16 += cmpyr(r21, r31)
|
||||
|
||||
# Complex multiply with round and pack
|
||||
# CHECK: d1 df 35 ed
|
||||
r17 = cmpy(r21, r31):rnd:sat
|
||||
# CHECK: d1 df b5 ed
|
||||
r17 = cmpy(r21, r31):<<1:rnd:sat
|
||||
# CHECK: d1 df 75 ed
|
||||
r17 = cmpy(r21, r31*):rnd:sat
|
||||
# CHECK: d1 df f5 ed
|
||||
r17 = cmpy(r21, r31*):<<1:rnd:sat
|
||||
|
||||
# Complex multiply 32x16
|
||||
# CHECK: 91 df 14 c5
|
||||
r17 = cmpyiwh(r21:20, r31):<<1:rnd:sat
|
||||
# CHECK: b1 df 14 c5
|
||||
r17 = cmpyiwh(r21:20, r31*):<<1:rnd:sat
|
||||
# CHECK: d1 df 14 c5
|
||||
r17 = cmpyrwh(r21:20, r31):<<1:rnd:sat
|
||||
# CHECK: f1 df 14 c5
|
||||
r17 = cmpyrwh(r21:20, r31*):<<1:rnd:sat
|
||||
|
||||
# Vector complex multiply real or imaginary
|
||||
# CHECK: d0 de 34 e8
|
||||
r17:16 = vcmpyr(r21:20, r31:30):sat
|
||||
# CHECK: d0 de b4 e8
|
||||
r17:16 = vcmpyr(r21:20, r31:30):<<1:sat
|
||||
# CHECK: d0 de 54 e8
|
||||
r17:16 = vcmpyi(r21:20, r31:30):sat
|
||||
# CHECK: d0 de d4 e8
|
||||
r17:16 = vcmpyi(r21:20, r31:30):<<1:sat
|
||||
# CHECK: 90 de 34 ea
|
||||
r17:16 += vcmpyr(r21:20, r31:30):sat
|
||||
# CHECK: 90 de 54 ea
|
||||
r17:16 += vcmpyi(r21:20, r31:30):sat
|
||||
|
||||
# Vector complex conjugate
|
||||
# CHECK: f0 c0 94 80
|
||||
r17:16 = vconj(r21:20):sat
|
||||
|
||||
# Vector complex rotate
|
||||
# CHECK: 10 df d4 c3
|
||||
r17:16 = vcrotate(r21:20, r31)
|
||||
|
||||
# Vector reduce complex multiply real or imaginary
|
||||
# CHECK: 10 de 14 e8
|
||||
r17:16 = vrcmpyi(r21:20, r31:30)
|
||||
# CHECK: 30 de 14 e8
|
||||
r17:16 = vrcmpyr(r21:20, r31:30)
|
||||
# CHECK: 10 de 54 e8
|
||||
r17:16 = vrcmpyi(r21:20, r31:30*)
|
||||
# CHECK: 30 de 74 e8
|
||||
r17:16 = vrcmpyr(r21:20, r31:30*)
|
||||
|
||||
# Vector reduce complex multiply by scalar
|
||||
# CHECK: 90 de b4 e8
|
||||
r17:16 = vrcmpys(r21:20, r31:30):<<1:sat:raw:hi
|
||||
# CHECK: 90 de f4 e8
|
||||
r17:16 = vrcmpys(r21:20, r31:30):<<1:sat:raw:lo
|
||||
# CHECK: 90 de b4 ea
|
||||
r17:16 += vrcmpys(r21:20, r31:30):<<1:sat:raw:hi
|
||||
# CHECK: 90 de f4 ea
|
||||
r17:16 += vrcmpys(r21:20, r31:30):<<1:sat:raw:lo
|
||||
|
||||
# Vector reduce complex multiply by scalar with round and pack
|
||||
# CHECK: d1 de b4 e9
|
||||
r17 = vrcmpys(r21:20, r31:30):<<1:rnd:sat:raw:hi
|
||||
# CHECK: f1 de b4 e9
|
||||
r17 = vrcmpys(r21:20, r31:30):<<1:rnd:sat:raw:lo
|
||||
|
||||
# Vector reduce complex rotate
|
||||
# CHECK: f0 ff d4 c3
|
||||
r17:16 = vrcrotate(r21:20, r31, #3)
|
||||
# CHECK: 30 ff b4 cb
|
||||
r17:16 += vrcrotate(r21:20, r31, #3)
|
146
test/MC/Hexagon/instructions/xtype_fp.s
Normal file
146
test/MC/Hexagon/instructions/xtype_fp.s
Normal file
@ -0,0 +1,146 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.10.4 XTYPE/FP
|
||||
|
||||
# Floating point addition
|
||||
# CHECK: 11 df 15 eb
|
||||
r17 = sfadd(r21, r31)
|
||||
|
||||
# Classify floating-point value
|
||||
# CHECK: 03 d5 f1 85
|
||||
p3 = sfclass(r17, #21)
|
||||
# CHECK: b3 c2 90 dc
|
||||
p3 = dfclass(r17:16, #21)
|
||||
|
||||
# Compare floating-point value
|
||||
# CHECK: 03 d5 f1 c7
|
||||
p3 = sfcmp.ge(r17, r21)
|
||||
# CHECK: 23 d5 f1 c7
|
||||
p3 = sfcmp.uo(r17, r21)
|
||||
# CHECK: 63 d5 f1 c7
|
||||
p3 = sfcmp.eq(r17, r21)
|
||||
# CHECK: 83 d5 f1 c7
|
||||
p3 = sfcmp.gt(r17, r21)
|
||||
# CHECK: 03 d4 f0 d2
|
||||
p3 = dfcmp.eq(r17:16, r21:20)
|
||||
# CHECK: 23 d4 f0 d2
|
||||
p3 = dfcmp.gt(r17:16, r21:20)
|
||||
# CHECK: 43 d4 f0 d2
|
||||
p3 = dfcmp.ge(r17:16, r21:20)
|
||||
# CHECK: 63 d4 f0 d2
|
||||
p3 = dfcmp.uo(r17:16, r21:20)
|
||||
|
||||
# Convert floating-point value to other format
|
||||
# CHECK: 10 c0 95 84
|
||||
r17:16 = convert_sf2df(r21)
|
||||
# CHECK: 31 c0 14 88
|
||||
r17 = convert_df2sf(r21:20)
|
||||
|
||||
# Convert integer to floating-point value
|
||||
# CHECK: 50 c0 f4 80
|
||||
r17:16 = convert_ud2df(r21:20)
|
||||
# CHECK: 70 c0 f4 80
|
||||
r17:16 = convert_d2df(r21:20)
|
||||
# CHECK: 30 c0 95 84
|
||||
r17:16 = convert_uw2df(r21)
|
||||
# CHECK: 50 c0 95 84
|
||||
r17:16 = convert_w2df(r21)
|
||||
# CHECK: 31 c0 34 88
|
||||
r17 = convert_ud2sf(r21:20)
|
||||
# CHECK: 31 c0 54 88
|
||||
r17 = convert_d2sf(r21:20)
|
||||
# CHECK: 11 c0 35 8b
|
||||
r17 = convert_uw2sf(r21)
|
||||
# CHECK: 11 c0 55 8b
|
||||
r17 = convert_w2sf(r21)
|
||||
|
||||
# Convert floating-point value to integer
|
||||
# CHECK: 10 c0 f4 80
|
||||
r17:16 = convert_df2d(r21:20)
|
||||
# CHECK: 30 c0 f4 80
|
||||
r17:16 = convert_df2ud(r21:20)
|
||||
# CHECK: d0 c0 f4 80
|
||||
r17:16 = convert_df2d(r21:20):chop
|
||||
# CHECK: f0 c0 f4 80
|
||||
r17:16 = convert_df2ud(r21:20):chop
|
||||
# CHECK: 70 c0 95 84
|
||||
r17:16 = convert_sf2ud(r21)
|
||||
# CHECK: 90 c0 95 84
|
||||
r17:16 = convert_sf2d(r21)
|
||||
# CHECK: b0 c0 95 84
|
||||
r17:16 = convert_sf2ud(r21):chop
|
||||
# CHECK: d0 c0 95 84
|
||||
r17:16 = convert_sf2d(r21):chop
|
||||
# CHECK: 31 c0 74 88
|
||||
r17 = convert_df2uw(r21:20)
|
||||
# CHECK: 31 c0 94 88
|
||||
r17 = convert_df2w(r21:20)
|
||||
# CHECK: 31 c0 b4 88
|
||||
r17 = convert_df2uw(r21:20):chop
|
||||
# CHECK: 31 c0 f4 88
|
||||
r17 = convert_df2w(r21:20):chop
|
||||
# CHECK: 11 c0 75 8b
|
||||
r17 = convert_sf2uw(r21)
|
||||
# CHECK: 31 c0 75 8b
|
||||
r17 = convert_sf2uw(r21):chop
|
||||
# CHECK: 11 c0 95 8b
|
||||
r17 = convert_sf2w(r21)
|
||||
# CHECK: 31 c0 95 8b
|
||||
r17 = convert_sf2w(r21):chop
|
||||
|
||||
# Floating point extreme value assistance
|
||||
# CHECK: 11 c0 b5 8b
|
||||
r17 = sffixupr(r21)
|
||||
# CHECK: 11 df d5 eb
|
||||
r17 = sffixupn(r21, r31)
|
||||
# CHECK: 31 df d5 eb
|
||||
r17 = sffixupd(r21, r31)
|
||||
|
||||
# Floating point fused multiply-add
|
||||
# CHECK: 91 df 15 ef
|
||||
r17 += sfmpy(r21, r31)
|
||||
# CHECK: b1 df 15 ef
|
||||
r17 -= sfmpy(r21, r31)
|
||||
|
||||
# Floating point fused multiply-add with scaling
|
||||
# CHECK: f1 df 75 ef
|
||||
r17 += sfmpy(r21, r31, p3):scale
|
||||
|
||||
# Floating point reciprocal square root approximation
|
||||
# CHECK: 71 c0 f5 8b
|
||||
r17, p3 = sfinvsqrta(r21)
|
||||
|
||||
# Floating point fused multiply-add for library routines
|
||||
# CHECK: d1 df 15 ef
|
||||
r17 += sfmpy(r21, r31):lib
|
||||
# CHECK: f1 df 15 ef
|
||||
r17 -= sfmpy(r21, r31):lib
|
||||
|
||||
# Create floating-point constant
|
||||
# CHECK: b1 c2 00 d6
|
||||
r17 = sfmake(#21):pos
|
||||
# CHECK: b1 c2 40 d6
|
||||
r17 = sfmake(#21):neg
|
||||
# CHECK: b0 c2 00 d9
|
||||
r17:16 = dfmake(#21):pos
|
||||
# CHECK: b0 c2 40 d9
|
||||
r17:16 = dfmake(#21):neg
|
||||
|
||||
# Floating point maximum
|
||||
# CHECK: 11 df 95 eb
|
||||
r17 = sfmax(r21, r31)
|
||||
|
||||
# Floating point minimum
|
||||
# CHECK: 31 df 95 eb
|
||||
r17 = sfmin(r21, r31)
|
||||
|
||||
# Floating point multiply
|
||||
# CHECK: 11 df 55 eb
|
||||
r17 = sfmpy(r21, r31)
|
||||
|
||||
# Floating point reciprocal approximation
|
||||
# CHECK: f1 df f5 eb
|
||||
r17, p3 = sfrecipa(r21, r31)
|
||||
|
||||
# Floating point subtraction
|
||||
# CHECK: 31 df 15 eb
|
||||
r17 = sfsub(r21, r31)
|
400
test/MC/Hexagon/instructions/xtype_mpy.s
Normal file
400
test/MC/Hexagon/instructions/xtype_mpy.s
Normal file
@ -0,0 +1,400 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.10.5 XTYPE/MPY
|
||||
|
||||
# Multiply and use lower result
|
||||
# CHECK: b1 df 35 d7
|
||||
r17 = add(#21, mpyi(r21, r31))
|
||||
# CHECK: bf d1 35 d8
|
||||
r17 = add(#21, mpyi(r21, #31))
|
||||
# CHECK: b5 d1 3f df
|
||||
r17 = add(r21, mpyi(#84, r31))
|
||||
# CHECK: f5 f1 b5 df
|
||||
r17 = add(r21, mpyi(r21, #31))
|
||||
# CHECK: 15 d1 1f e3
|
||||
r17 = add(r21, mpyi(r17, r31))
|
||||
# CHECK: f1 c3 15 e0
|
||||
r17 =+ mpyi(r21, #31)
|
||||
# CHECK: f1 c3 95 e0
|
||||
r17 =- mpyi(r21, #31)
|
||||
# CHECK: f1 c3 15 e1
|
||||
r17 += mpyi(r21, #31)
|
||||
# CHECK: f1 c3 95 e1
|
||||
r17 -= mpyi(r21, #31)
|
||||
# CHECK: 11 df 15 ed
|
||||
r17 = mpyi(r21, r31)
|
||||
# CHECK: 11 df 15 ef
|
||||
r17 += mpyi(r21, r31)
|
||||
|
||||
# Vector multiply word by signed half (32x16)
|
||||
# CHECK: b0 de 14 e8
|
||||
r17:16 = vmpyweh(r21:20, r31:30):sat
|
||||
# CHECK: b0 de 94 e8
|
||||
r17:16 = vmpyweh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: f0 de 14 e8
|
||||
r17:16 = vmpywoh(r21:20, r31:30):sat
|
||||
# CHECK: f0 de 94 e8
|
||||
r17:16 = vmpywoh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: b0 de 34 e8
|
||||
r17:16 = vmpyweh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: b0 de b4 e8
|
||||
r17:16 = vmpyweh(r21:20, r31:30):<<1:rnd:sat
|
||||
# CHECK: f0 de 34 e8
|
||||
r17:16 = vmpywoh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: f0 de b4 e8
|
||||
r17:16 = vmpywoh(r21:20, r31:30):<<1:rnd:sat
|
||||
# CHECK: b0 de 14 ea
|
||||
r17:16 += vmpyweh(r21:20, r31:30):sat
|
||||
# CHECK: b0 de 94 ea
|
||||
r17:16 += vmpyweh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: f0 de 14 ea
|
||||
r17:16 += vmpywoh(r21:20, r31:30):sat
|
||||
# CHECK: f0 de 94 ea
|
||||
r17:16 += vmpywoh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: b0 de 34 ea
|
||||
r17:16 += vmpyweh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: b0 de b4 ea
|
||||
r17:16 += vmpyweh(r21:20, r31:30):<<1:rnd:sat
|
||||
# CHECK: f0 de 34 ea
|
||||
r17:16 += vmpywoh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: f0 de b4 ea
|
||||
r17:16 += vmpywoh(r21:20, r31:30):<<1:rnd:sat
|
||||
|
||||
# Vector multiply word by unsigned half (32x16)
|
||||
# CHECK: b0 de 54 e8
|
||||
r17:16 = vmpyweuh(r21:20, r31:30):sat
|
||||
# CHECK: b0 de d4 e8
|
||||
r17:16 = vmpyweuh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: f0 de 54 e8
|
||||
r17:16 = vmpywouh(r21:20, r31:30):sat
|
||||
# CHECK: f0 de d4 e8
|
||||
r17:16 = vmpywouh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: b0 de 74 e8
|
||||
r17:16 = vmpyweuh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: b0 de f4 e8
|
||||
r17:16 = vmpyweuh(r21:20, r31:30):<<1:rnd:sat
|
||||
# CHECK: f0 de 74 e8
|
||||
r17:16 = vmpywouh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: f0 de f4 e8
|
||||
r17:16 = vmpywouh(r21:20, r31:30):<<1:rnd:sat
|
||||
# CHECK: b0 de 54 ea
|
||||
r17:16 += vmpyweuh(r21:20, r31:30):sat
|
||||
# CHECK: b0 de d4 ea
|
||||
r17:16 += vmpyweuh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: f0 de 54 ea
|
||||
r17:16 += vmpywouh(r21:20, r31:30):sat
|
||||
# CHECK: f0 de d4 ea
|
||||
r17:16 += vmpywouh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: b0 de 74 ea
|
||||
r17:16 += vmpyweuh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: b0 de f4 ea
|
||||
r17:16 += vmpyweuh(r21:20, r31:30):<<1:rnd:sat
|
||||
# CHECK: f0 de 74 ea
|
||||
r17:16 += vmpywouh(r21:20, r31:30):rnd:sat
|
||||
# CHECK: f0 de f4 ea
|
||||
r17:16 += vmpywouh(r21:20, r31:30):<<1:rnd:sat
|
||||
|
||||
# Multiply signed halfwords
|
||||
# CHECK: 10 df 95 e4
|
||||
r17:16 = mpy(r21.l, r31.l):<<1
|
||||
# CHECK: 30 df 95 e4
|
||||
r17:16 = mpy(r21.l, r31.h):<<1
|
||||
# CHECK: 50 df 95 e4
|
||||
r17:16 = mpy(r21.h, r31.l):<<1
|
||||
# CHECK: 70 df 95 e4
|
||||
r17:16 = mpy(r21.h, r31.h):<<1
|
||||
# CHECK: 10 df b5 e4
|
||||
r17:16 = mpy(r21.l, r31.l):<<1:rnd
|
||||
# CHECK: 30 df b5 e4
|
||||
r17:16 = mpy(r21.l, r31.h):<<1:rnd
|
||||
# CHECK: 50 df b5 e4
|
||||
r17:16 = mpy(r21.h, r31.l):<<1:rnd
|
||||
# CHECK: 70 df b5 e4
|
||||
r17:16 = mpy(r21.h, r31.h):<<1:rnd
|
||||
# CHECK: 10 df 95 e6
|
||||
r17:16 += mpy(r21.l, r31.l):<<1
|
||||
# CHECK: 30 df 95 e6
|
||||
r17:16 += mpy(r21.l, r31.h):<<1
|
||||
# CHECK: 50 df 95 e6
|
||||
r17:16 += mpy(r21.h, r31.l):<<1
|
||||
# CHECK: 70 df 95 e6
|
||||
r17:16 += mpy(r21.h, r31.h):<<1
|
||||
# CHECK: 10 df b5 e6
|
||||
r17:16 -= mpy(r21.l, r31.l):<<1
|
||||
# CHECK: 30 df b5 e6
|
||||
r17:16 -= mpy(r21.l, r31.h):<<1
|
||||
# CHECK: 50 df b5 e6
|
||||
r17:16 -= mpy(r21.h, r31.l):<<1
|
||||
# CHECK: 70 df b5 e6
|
||||
r17:16 -= mpy(r21.h, r31.h):<<1
|
||||
# CHECK: 11 df 95 ec
|
||||
r17 = mpy(r21.l, r31.l):<<1
|
||||
# CHECK: 31 df 95 ec
|
||||
r17 = mpy(r21.l, r31.h):<<1
|
||||
# CHECK: 51 df 95 ec
|
||||
r17 = mpy(r21.h, r31.l):<<1
|
||||
# CHECK: 71 df 95 ec
|
||||
r17 = mpy(r21.h, r31.h):<<1
|
||||
# CHECK: 91 df 95 ec
|
||||
r17 = mpy(r21.l, r31.l):<<1:sat
|
||||
# CHECK: b1 df 95 ec
|
||||
r17 = mpy(r21.l, r31.h):<<1:sat
|
||||
# CHECK: d1 df 95 ec
|
||||
r17 = mpy(r21.h, r31.l):<<1:sat
|
||||
# CHECK: f1 df 95 ec
|
||||
r17 = mpy(r21.h, r31.h):<<1:sat
|
||||
# CHECK: 11 df b5 ec
|
||||
r17 = mpy(r21.l, r31.l):<<1:rnd
|
||||
# CHECK: 31 df b5 ec
|
||||
r17 = mpy(r21.l, r31.h):<<1:rnd
|
||||
# CHECK: 51 df b5 ec
|
||||
r17 = mpy(r21.h, r31.l):<<1:rnd
|
||||
# CHECK: 71 df b5 ec
|
||||
r17 = mpy(r21.h, r31.h):<<1:rnd
|
||||
# CHECK: 91 df b5 ec
|
||||
r17 = mpy(r21.l, r31.l):<<1:rnd:sat
|
||||
# CHECK: b1 df b5 ec
|
||||
r17 = mpy(r21.l, r31.h):<<1:rnd:sat
|
||||
# CHECK: d1 df b5 ec
|
||||
r17 = mpy(r21.h, r31.l):<<1:rnd:sat
|
||||
# CHECK: f1 df b5 ec
|
||||
r17 = mpy(r21.h, r31.h):<<1:rnd:sat
|
||||
# CHECK: 11 df 95 ee
|
||||
r17 += mpy(r21.l, r31.l):<<1
|
||||
# CHECK: 31 df 95 ee
|
||||
r17 += mpy(r21.l, r31.h):<<1
|
||||
# CHECK: 51 df 95 ee
|
||||
r17 += mpy(r21.h, r31.l):<<1
|
||||
# CHECK: 71 df 95 ee
|
||||
r17 += mpy(r21.h, r31.h):<<1
|
||||
# CHECK: 91 df 95 ee
|
||||
r17 += mpy(r21.l, r31.l):<<1:sat
|
||||
# CHECK: b1 df 95 ee
|
||||
r17 += mpy(r21.l, r31.h):<<1:sat
|
||||
# CHECK: d1 df 95 ee
|
||||
r17 += mpy(r21.h, r31.l):<<1:sat
|
||||
# CHECK: f1 df 95 ee
|
||||
r17 += mpy(r21.h, r31.h):<<1:sat
|
||||
# CHECK: 11 df b5 ee
|
||||
r17 -= mpy(r21.l, r31.l):<<1
|
||||
# CHECK: 31 df b5 ee
|
||||
r17 -= mpy(r21.l, r31.h):<<1
|
||||
# CHECK: 51 df b5 ee
|
||||
r17 -= mpy(r21.h, r31.l):<<1
|
||||
# CHECK: 71 df b5 ee
|
||||
r17 -= mpy(r21.h, r31.h):<<1
|
||||
# CHECK: 91 df b5 ee
|
||||
r17 -= mpy(r21.l, r31.l):<<1:sat
|
||||
# CHECK: b1 df b5 ee
|
||||
r17 -= mpy(r21.l, r31.h):<<1:sat
|
||||
# CHECK: d1 df b5 ee
|
||||
r17 -= mpy(r21.h, r31.l):<<1:sat
|
||||
# CHECK: f1 df b5 ee
|
||||
r17 -= mpy(r21.h, r31.h):<<1:sat
|
||||
|
||||
# Multiply unsigned halfwords
|
||||
# CHECK: 10 df d5 e4
|
||||
r17:16 = mpyu(r21.l, r31.l):<<1
|
||||
# CHECK: 30 df d5 e4
|
||||
r17:16 = mpyu(r21.l, r31.h):<<1
|
||||
# CHECK: 50 df d5 e4
|
||||
r17:16 = mpyu(r21.h, r31.l):<<1
|
||||
# CHECK: 70 df d5 e4
|
||||
r17:16 = mpyu(r21.h, r31.h):<<1
|
||||
# CHECK: 10 df d5 e6
|
||||
r17:16 += mpyu(r21.l, r31.l):<<1
|
||||
# CHECK: 30 df d5 e6
|
||||
r17:16 += mpyu(r21.l, r31.h):<<1
|
||||
# CHECK: 50 df d5 e6
|
||||
r17:16 += mpyu(r21.h, r31.l):<<1
|
||||
# CHECK: 70 df d5 e6
|
||||
r17:16 += mpyu(r21.h, r31.h):<<1
|
||||
# CHECK: 10 df f5 e6
|
||||
r17:16 -= mpyu(r21.l, r31.l):<<1
|
||||
# CHECK: 30 df f5 e6
|
||||
r17:16 -= mpyu(r21.l, r31.h):<<1
|
||||
# CHECK: 50 df f5 e6
|
||||
r17:16 -= mpyu(r21.h, r31.l):<<1
|
||||
# CHECK: 70 df f5 e6
|
||||
r17:16 -= mpyu(r21.h, r31.h):<<1
|
||||
# CHECK: 11 df d5 ec
|
||||
r17 = mpyu(r21.l, r31.l):<<1
|
||||
# CHECK: 31 df d5 ec
|
||||
r17 = mpyu(r21.l, r31.h):<<1
|
||||
# CHECK: 51 df d5 ec
|
||||
r17 = mpyu(r21.h, r31.l):<<1
|
||||
# CHECK: 71 df d5 ec
|
||||
r17 = mpyu(r21.h, r31.h):<<1
|
||||
# CHECK: 11 df d5 ee
|
||||
r17 += mpyu(r21.l, r31.l):<<1
|
||||
# CHECK: 31 df d5 ee
|
||||
r17 += mpyu(r21.l, r31.h):<<1
|
||||
# CHECK: 51 df d5 ee
|
||||
r17 += mpyu(r21.h, r31.l):<<1
|
||||
# CHECK: 71 df d5 ee
|
||||
r17 += mpyu(r21.h, r31.h):<<1
|
||||
# CHECK: 11 df f5 ee
|
||||
r17 -= mpyu(r21.l, r31.l):<<1
|
||||
# CHECK: 31 df f5 ee
|
||||
r17 -= mpyu(r21.l, r31.h):<<1
|
||||
# CHECK: 51 df f5 ee
|
||||
r17 -= mpyu(r21.h, r31.l):<<1
|
||||
# CHECK: 71 df f5 ee
|
||||
r17 -= mpyu(r21.h, r31.h):<<1
|
||||
|
||||
# Polynomial multiply words
|
||||
# CHECK: f0 df 55 e5
|
||||
r17:16 = pmpyw(r21, r31)
|
||||
# CHECK: f0 df 35 e7
|
||||
r17:16 ^= pmpyw(r21, r31)
|
||||
|
||||
# Vector reduce multiply word by signed half (32x16)
|
||||
# CHECK: 50 de 34 e8
|
||||
r17:16 = vrmpywoh(r21:20, r31:30)
|
||||
# CHECK: 50 de b4 e8
|
||||
r17:16 = vrmpywoh(r21:20, r31:30):<<1
|
||||
# CHECK: 90 de 54 e8
|
||||
r17:16 = vrmpyweh(r21:20, r31:30)
|
||||
# CHECK: 90 de d4 e8
|
||||
r17:16 = vrmpyweh(r21:20, r31:30):<<1
|
||||
# CHECK: d0 de 74 ea
|
||||
r17:16 += vrmpywoh(r21:20, r31:30)
|
||||
# CHECK: d0 de f4 ea
|
||||
r17:16 += vrmpywoh(r21:20, r31:30):<<1
|
||||
# CHECK: d0 de 34 ea
|
||||
r17:16 += vrmpyweh(r21:20, r31:30)
|
||||
# CHECK: d0 de b4 ea
|
||||
r17:16 += vrmpyweh(r21:20, r31:30):<<1
|
||||
|
||||
# Multiply and use upper result
|
||||
# CHECK: 31 df 15 ed
|
||||
r17 = mpy(r21, r31)
|
||||
# CHECK: 31 df 35 ed
|
||||
r17 = mpy(r21, r31):rnd
|
||||
# CHECK: 31 df 55 ed
|
||||
r17 = mpyu(r21, r31)
|
||||
# CHECK: 31 df 75 ed
|
||||
r17 = mpysu(r21, r31)
|
||||
# CHECK: 11 df b5 ed
|
||||
r17 = mpy(r21, r31.h):<<1:sat
|
||||
# CHECK: 31 df b5 ed
|
||||
r17 = mpy(r21, r31.l):<<1:sat
|
||||
# CHECK: 91 df b5 ed
|
||||
r17 = mpy(r21, r31.h):<<1:rnd:sat
|
||||
# CHECK: 11 df f5 ed
|
||||
r17 = mpy(r21, r31):<<1:sat
|
||||
# CHECK: 91 df f5 ed
|
||||
r17 = mpy(r21, r31.l):<<1:rnd:sat
|
||||
# CHECK: 51 df b5 ed
|
||||
r17 = mpy(r21, r31):<<1
|
||||
# CHECK: 11 df 75 ef
|
||||
r17 += mpy(r21, r31):<<1:sat
|
||||
# CHECK: 31 df 75 ef
|
||||
r17 -= mpy(r21, r31):<<1:sat
|
||||
|
||||
# Multiply and use full result
|
||||
# CHECK: 10 df 15 e5
|
||||
r17:16 = mpy(r21, r31)
|
||||
# CHECK: 10 df 55 e5
|
||||
r17:16 = mpyu(r21, r31)
|
||||
# CHECK: 10 df 15 e7
|
||||
r17:16 += mpy(r21, r31)
|
||||
# CHECK: 10 df 35 e7
|
||||
r17:16 -= mpy(r21, r31)
|
||||
# CHECK: 10 df 55 e7
|
||||
r17:16 += mpyu(r21, r31)
|
||||
# CHECK: 10 df 75 e7
|
||||
r17:16 -= mpyu(r21, r31)
|
||||
|
||||
# Vector dual multiply
|
||||
# CHECK: 90 de 14 e8
|
||||
r17:16 = vdmpy(r21:20, r31:30):sat
|
||||
# CHECK: 90 de 94 e8
|
||||
r17:16 = vdmpy(r21:20, r31:30):<<1:sat
|
||||
# CHECK: 90 de 14 ea
|
||||
r17:16 += vdmpy(r21:20, r31:30):sat
|
||||
# CHECK: 90 de 94 ea
|
||||
r17:16 += vdmpy(r21:20, r31:30):<<1:sat
|
||||
|
||||
# Vector dual multiply with round and pack
|
||||
# CHECK: 11 de 14 e9
|
||||
r17 = vdmpy(r21:20, r31:30):rnd:sat
|
||||
# CHECK: 11 de 94 e9
|
||||
r17 = vdmpy(r21:20, r31:30):<<1:rnd:sat
|
||||
|
||||
# Vector reduce multiply bytes
|
||||
# CHECK: 30 de 94 e8
|
||||
r17:16 = vrmpybu(r21:20, r31:30)
|
||||
# CHECK: 30 de d4 e8
|
||||
r17:16 = vrmpybsu(r21:20, r31:30)
|
||||
# CHECK: 30 de 94 ea
|
||||
r17:16 += vrmpybu(r21:20, r31:30)
|
||||
# CHECK: 30 de d4 ea
|
||||
r17:16 += vrmpybsu(r21:20, r31:30)
|
||||
|
||||
# Vector dual multiply signed by unsigned bytes
|
||||
# CHECK: 30 de b4 e8
|
||||
r17:16 = vdmpybsu(r21:20, r31:30):sat
|
||||
# CHECK: 30 de 34 ea
|
||||
r17:16 += vdmpybsu(r21:20, r31:30):sat
|
||||
|
||||
# Vector multiply even haldwords
|
||||
# CHECK: d0 de 14 e8
|
||||
r17:16 = vmpyeh(r21:20, r31:30):sat
|
||||
# CHECK: d0 de 94 e8
|
||||
r17:16 = vmpyeh(r21:20, r31:30):<<1:sat
|
||||
# CHECK: 50 de 34 ea
|
||||
r17:16 += vmpyeh(r21:20, r31:30)
|
||||
# CHECK: d0 de 14 ea
|
||||
r17:16 += vmpyeh(r21:20, r31:30):sat
|
||||
# CHECK: d0 de 94 ea
|
||||
r17:16 += vmpyeh(r21:20, r31:30):<<1:sat
|
||||
|
||||
# Vector multiply halfwords
|
||||
# CHECK: b0 df 15 e5
|
||||
r17:16 = vmpyh(r21, r31):sat
|
||||
# CHECK: b0 df 95 e5
|
||||
r17:16 = vmpyh(r21, r31):<<1:sat
|
||||
# CHECK: 30 df 35 e7
|
||||
r17:16 += vmpyh(r21, r31)
|
||||
# CHECK: b0 df 15 e7
|
||||
r17:16 += vmpyh(r21, r31):sat
|
||||
# CHECK: b0 df 95 e7
|
||||
r17:16 += vmpyh(r21, r31):<<1:sat
|
||||
|
||||
# Vector multiply halfwords with round and pack
|
||||
# CHECK: f1 df 35 ed
|
||||
r17 = vmpyh(r21, r31):rnd:sat
|
||||
# CHECK: f1 df b5 ed
|
||||
r17 = vmpyh(r21, r31):<<1:rnd:sat
|
||||
|
||||
# Vector multiply halfwords signed by unsigned
|
||||
# CHECK: f0 df 15 e5
|
||||
r17:16 = vmpyhsu(r21, r31):sat
|
||||
# CHECK: f0 df 95 e5
|
||||
r17:16 = vmpyhsu(r21, r31):<<1:sat
|
||||
# CHECK: b0 df 75 e7
|
||||
r17:16 += vmpyhsu(r21, r31):sat
|
||||
# CHECK: b0 df f5 e7
|
||||
r17:16 += vmpyhsu(r21, r31):<<1:sat
|
||||
|
||||
# Vector reduce multiply halfwords
|
||||
# CHECK: 50 de 14 e8
|
||||
r17:16 = vrmpyh(r21:20, r31:30)
|
||||
# CHECK: 50 de 14 ea
|
||||
r17:16 += vrmpyh(r21:20, r31:30)
|
||||
|
||||
# Vector multiply bytes
|
||||
# CHECK: 30 df 55 e5
|
||||
r17:16 = vmpybsu(r21, r31)
|
||||
# CHECK: 30 df 95 e5
|
||||
r17:16 = vmpybu(r21, r31)
|
||||
# CHECK: 30 df 95 e7
|
||||
r17:16 += vmpybu(r21, r31)
|
||||
# CHECK: 30 df d5 e7
|
||||
r17:16 += vmpybsu(r21, r31)
|
||||
|
||||
# Vector polynomial multiply halfwords
|
||||
# CHECK: f0 df d5 e5
|
||||
r17:16 = vpmpyh(r21, r31)
|
||||
# CHECK: f0 df b5 e7
|
||||
r17:16 ^= vpmpyh(r21, r31)
|
104
test/MC/Hexagon/instructions/xtype_perm.s
Normal file
104
test/MC/Hexagon/instructions/xtype_perm.s
Normal file
@ -0,0 +1,104 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.10.6 XTYPE/PERM
|
||||
|
||||
# CABAC decode bin
|
||||
# CHECK: d0 de d4 c1
|
||||
r17:16 = decbin(r21:20, r31:30)
|
||||
|
||||
# Saturate
|
||||
# CHECK: 11 c0 d4 88
|
||||
r17 = sat(r21:20)
|
||||
# CHECK: 91 c0 d5 8c
|
||||
r17 = sath(r21)
|
||||
# CHECK: b1 c0 d5 8c
|
||||
r17 = satuh(r21)
|
||||
# CHECK: d1 c0 d5 8c
|
||||
r17 = satub(r21)
|
||||
# CHECK: f1 c0 d5 8c
|
||||
r17 = satb(r21)
|
||||
|
||||
# Swizzle bytes
|
||||
# CHECK: f1 c0 95 8c
|
||||
r17 = swiz(r21)
|
||||
|
||||
# Vector align
|
||||
# CHECK: 70 d4 1e c2
|
||||
r17:16 = valignb(r21:20, r31:30, p3)
|
||||
# CHECK: 70 de 94 c2
|
||||
r17:16 = vspliceb(r21:20, r31:30, p3)
|
||||
|
||||
# Vector round and pack
|
||||
# CHECK: 91 c0 94 88
|
||||
r17 = vrndwh(r21:20)
|
||||
# CHECK: d1 c0 94 88
|
||||
r17 = vrndwh(r21:20):sat
|
||||
|
||||
# Vector saturate and pack
|
||||
# CHECK: 11 c0 14 88
|
||||
r17 = vsathub(r21:20)
|
||||
# CHECK: 51 c0 14 88
|
||||
r17 = vsatwh(r21:20)
|
||||
# CHECK: 91 c0 14 88
|
||||
r17 = vsatwuh(r21:20)
|
||||
# CHECK: d1 c0 14 88
|
||||
r17 = vsathb(r21:20)
|
||||
# CHECK: 11 c0 95 8c
|
||||
r17 = vsathb(r21)
|
||||
# CHECK: 51 c0 95 8c
|
||||
r17 = vsathub(r21)
|
||||
|
||||
# Vector saturate without pack
|
||||
# CHECK: 90 c0 14 80
|
||||
r17:16 = vsathub(r21:20)
|
||||
# CHECK: b0 c0 14 80
|
||||
r17:16 = vsatwuh(r21:20)
|
||||
# CHECK: d0 c0 14 80
|
||||
r17:16 = vsatwh(r21:20)
|
||||
# CHECK: f0 c0 14 80
|
||||
r17:16 = vsathb(r21:20)
|
||||
|
||||
# Vector shuffle
|
||||
# CHECK: 50 de 14 c1
|
||||
r17:16 = shuffeb(r21:20, r31:30)
|
||||
# CHECK: 90 d4 1e c1
|
||||
r17:16 = shuffob(r21:20, r31:30)
|
||||
# CHECK: d0 de 14 c1
|
||||
r17:16 = shuffeh(r21:20, r31:30)
|
||||
# CHECK: 10 d4 9e c1
|
||||
r17:16 = shuffoh(r21:20, r31:30)
|
||||
|
||||
# Vector splat bytes
|
||||
# CHECK: f1 c0 55 8c
|
||||
r17 = vsplatb(r21)
|
||||
|
||||
# Vector splat halfwords
|
||||
# CHECK: 50 c0 55 84
|
||||
r17:16 = vsplath(r21)
|
||||
|
||||
# Vector splice
|
||||
# CHECK: 70 de 94 c0
|
||||
r17:16 = vspliceb(r21:20, r31:30, #3)
|
||||
# CHECK: 70 de 94 c2
|
||||
r17:16 = vspliceb(r21:20, r31:30, p3)
|
||||
|
||||
# Vector sign extend
|
||||
# CHECK: 10 c0 15 84
|
||||
r17:16 = vsxtbh(r21)
|
||||
# CHECK: 90 c0 15 84
|
||||
r17:16 = vsxthw(r21)
|
||||
|
||||
# Vector truncate
|
||||
# CHECK: 11 c0 94 88
|
||||
r17 = vtrunohb(r21:20)
|
||||
# CHECK: 51 c0 94 88
|
||||
r17 = vtrunehb(r21:20)
|
||||
# CHECK: 50 de 94 c1
|
||||
r17:16 = vtrunewh(r21:20, r31:30)
|
||||
# CHECK: 90 de 94 c1
|
||||
r17:16 = vtrunowh(r21:20, r31:30)
|
||||
|
||||
# Vector zero extend
|
||||
# CHECK: 50 c0 15 84
|
||||
r17:16 = vzxtbh(r21)
|
||||
# CHECK: d0 c0 15 84
|
||||
r17:16 = vzxthw(r21)
|
136
test/MC/Hexagon/instructions/xtype_pred.s
Normal file
136
test/MC/Hexagon/instructions/xtype_pred.s
Normal file
@ -0,0 +1,136 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.10.7 XTYPE/PRED
|
||||
|
||||
# Bounds check
|
||||
# CHECK: 83 f4 10 d2
|
||||
p3 = boundscheck(r17:16, r21:20):raw:lo
|
||||
# CHECK: a3 f4 10 d2
|
||||
p3 = boundscheck(r17:16, r21:20):raw:hi
|
||||
|
||||
# Compare byte
|
||||
# CHECK: 43 d5 d1 c7
|
||||
p3 = cmpb.gt(r17, r21)
|
||||
# CHECK: c3 d5 d1 c7
|
||||
p3 = cmpb.eq(r17, r21)
|
||||
# CHECK: e3 d5 d1 c7
|
||||
p3 = cmpb.gtu(r17, r21)
|
||||
# CHECK: a3 c2 11 dd
|
||||
p3 = cmpb.eq(r17, #21)
|
||||
# CHECK: a3 c2 31 dd
|
||||
p3 = cmpb.gt(r17, #21)
|
||||
# CHECK: a3 c2 51 dd
|
||||
p3 = cmpb.gtu(r17, #21)
|
||||
|
||||
# Compare half
|
||||
# CHECK: 63 d5 d1 c7
|
||||
p3 = cmph.eq(r17, r21)
|
||||
# CHECK: 83 d5 d1 c7
|
||||
p3 = cmph.gt(r17, r21)
|
||||
# CHECK: a3 d5 d1 c7
|
||||
p3 = cmph.gtu(r17, r21)
|
||||
# CHECK: ab c2 11 dd
|
||||
p3 = cmph.eq(r17, #21)
|
||||
# CHECK: ab c2 31 dd
|
||||
p3 = cmph.gt(r17, #21)
|
||||
# CHECK: ab c2 51 dd
|
||||
p3 = cmph.gtu(r17, #21)
|
||||
|
||||
# Compare doublewords
|
||||
# CHECK: 03 de 94 d2
|
||||
p3 = cmp.eq(r21:20, r31:30)
|
||||
# CHECK: 43 de 94 d2
|
||||
p3 = cmp.gt(r21:20, r31:30)
|
||||
# CHECK: 83 de 94 d2
|
||||
p3 = cmp.gtu(r21:20, r31:30)
|
||||
|
||||
# Compare bitmask
|
||||
# CHECK: 03 d5 91 85
|
||||
p3 = bitsclr(r17, #21)
|
||||
# CHECK: 03 d5 b1 85
|
||||
p3 = !bitsclr(r17, #21)
|
||||
# CHECK: 03 d5 51 c7
|
||||
p3 = bitsset(r17, r21)
|
||||
# CHECK: 03 d5 71 c7
|
||||
p3 = !bitsset(r17, r21)
|
||||
# CHECK: 03 d5 91 c7
|
||||
p3 = bitsclr(r17, r21)
|
||||
# CHECK: 03 d5 b1 c7
|
||||
p3 = !bitsclr(r17, r21)
|
||||
|
||||
# mask generate from predicate
|
||||
# CHECK: 10 c3 00 86
|
||||
r17:16 = mask(p3)
|
||||
|
||||
# Check for TLB match
|
||||
# CHECK: 63 f5 10 d2
|
||||
p3 = tlbmatch(r17:16, r21)
|
||||
|
||||
# Predicate Transfer
|
||||
# CHECK: 03 c0 45 85
|
||||
p3 = r5
|
||||
# CHECK: 05 c0 43 89
|
||||
r5 = p3
|
||||
|
||||
# Test bit
|
||||
# CHECK: 03 d5 11 85
|
||||
p3 = tstbit(r17, #21)
|
||||
# CHECK: 03 d5 31 85
|
||||
p3 = !tstbit(r17, #21)
|
||||
# CHECK: 03 d5 11 c7
|
||||
p3 = tstbit(r17, r21)
|
||||
# CHECK: 03 d5 31 c7
|
||||
p3 = !tstbit(r17, r21)
|
||||
|
||||
# Vector compare halfwords
|
||||
# CHECK: 63 de 14 d2
|
||||
p3 = vcmph.eq(r21:20, r31:30)
|
||||
# CHECK: 83 de 14 d2
|
||||
p3 = vcmph.gt(r21:20, r31:30)
|
||||
# CHECK: a3 de 14 d2
|
||||
p3 = vcmph.gtu(r21:20, r31:30)
|
||||
# CHECK: eb c3 14 dc
|
||||
p3 = vcmph.eq(r21:20, #31)
|
||||
# CHECK: eb c3 34 dc
|
||||
p3 = vcmph.gt(r21:20, #31)
|
||||
# CHECK: eb c3 54 dc
|
||||
p3 = vcmph.gtu(r21:20, #31)
|
||||
|
||||
# Vector compare bytes for any match
|
||||
# CHECK: 03 fe 14 d2
|
||||
p3 = any8(vcmpb.eq(r21:20, r31:30))
|
||||
|
||||
# Vector compare bytes
|
||||
# CHECK: 63 de 14 d2
|
||||
p3 = vcmph.eq(r21:20, r31:30)
|
||||
# CHECK: 83 de 14 d2
|
||||
p3 = vcmph.gt(r21:20, r31:30)
|
||||
# CHECK: a3 de 14 d2
|
||||
p3 = vcmph.gtu(r21:20, r31:30)
|
||||
# CHECK: eb c3 14 dc
|
||||
p3 = vcmph.eq(r21:20, #31)
|
||||
# CHECK: eb c3 34 dc
|
||||
p3 = vcmph.gt(r21:20, #31)
|
||||
# CHECK: eb c3 54 dc
|
||||
p3 = vcmph.gtu(r21:20, #31)
|
||||
|
||||
# Vector compare words
|
||||
# CHECK: 03 de 14 d2
|
||||
p3 = vcmpw.eq(r21:20, r31:30)
|
||||
# CHECK: 23 de 14 d2
|
||||
p3 = vcmpw.gt(r21:20, r31:30)
|
||||
# CHECK: 43 de 14 d2
|
||||
p3 = vcmpw.gtu(r21:20, r31:30)
|
||||
# CHECK: f3 c3 14 dc
|
||||
p3 = vcmpw.eq(r21:20, #31)
|
||||
# CHECK: f3 c3 34 dc
|
||||
p3 = vcmpw.gt(r21:20, #31)
|
||||
# CHECK: f3 c3 54 dc
|
||||
p3 = vcmpw.gtu(r21:20, #31)
|
||||
|
||||
# Viterbi pack even and odd predicate bits
|
||||
# CHECK: 11 c2 03 89
|
||||
r17 = vitpack(p3, p2)
|
||||
|
||||
# Vector mux
|
||||
# CHECK: 70 de 14 d1
|
||||
r17:16 = vmux(p3, r21:20, r31:30)
|
260
test/MC/Hexagon/instructions/xtype_shift.s
Normal file
260
test/MC/Hexagon/instructions/xtype_shift.s
Normal file
@ -0,0 +1,260 @@
|
||||
# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
# Hexagon Programmer's Reference Manual 11.10.8 XTYPE/SHIFT
|
||||
|
||||
# Shift by immediate
|
||||
# CHECK: 10 df 14 80
|
||||
r17:16 = asr(r21:20, #31)
|
||||
# CHECK: 30 df 14 80
|
||||
r17:16 = lsr(r21:20, #31)
|
||||
# CHECK: 50 df 14 80
|
||||
r17:16 = asl(r21:20, #31)
|
||||
# CHECK: 11 df 15 8c
|
||||
r17 = asr(r21, #31)
|
||||
# CHECK: 31 df 15 8c
|
||||
r17 = lsr(r21, #31)
|
||||
# CHECK: 51 df 15 8c
|
||||
r17 = asl(r21, #31)
|
||||
|
||||
# Shift by immediate and accumulate
|
||||
# CHECK: 10 df 14 82
|
||||
r17:16 -= asr(r21:20, #31)
|
||||
# CHECK: 30 df 14 82
|
||||
r17:16 -= lsr(r21:20, #31)
|
||||
# CHECK: 50 df 14 82
|
||||
r17:16 -= asl(r21:20, #31)
|
||||
# CHECK: 90 df 14 82
|
||||
r17:16 += asr(r21:20, #31)
|
||||
# CHECK: b0 df 14 82
|
||||
r17:16 += lsr(r21:20, #31)
|
||||
# CHECK: d0 df 14 82
|
||||
r17:16 += asl(r21:20, #31)
|
||||
# CHECK: 11 df 15 8e
|
||||
r17 -= asr(r21, #31)
|
||||
# CHECK: 31 df 15 8e
|
||||
r17 -= lsr(r21, #31)
|
||||
# CHECK: 51 df 15 8e
|
||||
r17 -= asl(r21, #31)
|
||||
# CHECK: 91 df 15 8e
|
||||
r17 += asr(r21, #31)
|
||||
# CHECK: b1 df 15 8e
|
||||
r17 += lsr(r21, #31)
|
||||
# CHECK: d1 df 15 8e
|
||||
r17 += asl(r21, #31)
|
||||
# CHECK: 4c f7 11 de
|
||||
r17 = add(#21, asl(r17, #23))
|
||||
# CHECK: 4e f7 11 de
|
||||
r17 = sub(#21, asl(r17, #23))
|
||||
# CHECK: 5c f7 11 de
|
||||
r17 = add(#21, lsr(r17, #23))
|
||||
# CHECK: 5e f7 11 de
|
||||
r17 = sub(#21, lsr(r17, #23))
|
||||
|
||||
# Shift by immediate and add
|
||||
# CHECK: f1 d5 1f c4
|
||||
r17 = addasl(r21, r31, #7)
|
||||
|
||||
# Shift by immediate and logical
|
||||
# CHECK: 10 df 54 82
|
||||
r17:16 &= asr(r21:20, #31)
|
||||
# CHECK: 30 df 54 82
|
||||
r17:16 &= lsr(r21:20, #31)
|
||||
# CHECK: 50 df 54 82
|
||||
r17:16 &= asl(r21:20, #31)
|
||||
# CHECK: 90 df 54 82
|
||||
r17:16 |= asr(r21:20, #31)
|
||||
# CHECK: b0 df 54 82
|
||||
r17:16 |= lsr(r21:20, #31)
|
||||
# CHECK: d0 df 54 82
|
||||
r17:16 |= asl(r21:20, #31)
|
||||
# CHECK: 30 df 94 82
|
||||
r17:16 ^= lsr(r21:20, #31)
|
||||
# CHECK: 50 df 94 82
|
||||
r17:16 ^= asl(r21:20, #31)
|
||||
# CHECK: 11 df 55 8e
|
||||
r17 &= asr(r21, #31)
|
||||
# CHECK: 31 df 55 8e
|
||||
r17 &= lsr(r21, #31)
|
||||
# CHECK: 51 df 55 8e
|
||||
r17 &= asl(r21, #31)
|
||||
# CHECK: 91 df 55 8e
|
||||
r17 |= asr(r21, #31)
|
||||
# CHECK: b1 df 55 8e
|
||||
r17 |= lsr(r21, #31)
|
||||
# CHECK: d1 df 55 8e
|
||||
r17 |= asl(r21, #31)
|
||||
# CHECK: 31 df 95 8e
|
||||
r17 ^= lsr(r21, #31)
|
||||
# CHECK: 51 df 95 8e
|
||||
r17 ^= asl(r21, #31)
|
||||
# CHECK: 48 ff 11 de
|
||||
r17 = and(#21, asl(r17, #31))
|
||||
# CHECK: 4a ff 11 de
|
||||
r17 = or(#21, asl(r17, #31))
|
||||
# CHECK: 58 ff 11 de
|
||||
r17 = and(#21, lsr(r17, #31))
|
||||
# CHECK: 5a ff 11 de
|
||||
r17 = or(#21, lsr(r17, #31))
|
||||
|
||||
# Shift right by immediate with rounding
|
||||
# CHECK: f0 df d4 80
|
||||
r17:16 = asr(r21:20, #31):rnd
|
||||
# CHECK: 11 df 55 8c
|
||||
r17 = asr(r21, #31):rnd
|
||||
|
||||
# Shift left by immediate with saturation
|
||||
# CHECK: 51 df 55 8c
|
||||
r17 = asl(r21, #31):sat
|
||||
|
||||
# Shift by register
|
||||
# CHECK: 10 df 94 c3
|
||||
r17:16 = asr(r21:20, r31)
|
||||
# CHECK: 50 df 94 c3
|
||||
r17:16 = lsr(r21:20, r31)
|
||||
# CHECK: 90 df 94 c3
|
||||
r17:16 = asl(r21:20, r31)
|
||||
# CHECK: d0 df 94 c3
|
||||
r17:16 = lsl(r21:20, r31)
|
||||
# CHECK: 11 df 55 c6
|
||||
r17 = asr(r21, r31)
|
||||
# CHECK: 51 df 55 c6
|
||||
r17 = lsr(r21, r31)
|
||||
# CHECK: 91 df 55 c6
|
||||
r17 = asl(r21, r31)
|
||||
# CHECK: d1 df 55 c6
|
||||
r17 = lsl(r21, r31)
|
||||
# CHECK: f1 df 8a c6
|
||||
r17 = lsl(#21, r31)
|
||||
|
||||
# Shift by register and accumulate
|
||||
# CHECK: 10 df 94 cb
|
||||
r17:16 -= asr(r21:20, r31)
|
||||
# CHECK: 50 df 94 cb
|
||||
r17:16 -= lsr(r21:20, r31)
|
||||
# CHECK: 90 df 94 cb
|
||||
r17:16 -= asl(r21:20, r31)
|
||||
# CHECK: d0 df 94 cb
|
||||
r17:16 -= lsl(r21:20, r31)
|
||||
# CHECK: 10 df d4 cb
|
||||
r17:16 += asr(r21:20, r31)
|
||||
# CHECK: 50 df d4 cb
|
||||
r17:16 += lsr(r21:20, r31)
|
||||
# CHECK: 90 df d4 cb
|
||||
r17:16 += asl(r21:20, r31)
|
||||
# CHECK: d0 df d4 cb
|
||||
r17:16 += lsl(r21:20, r31)
|
||||
# CHECK: 11 df 95 cc
|
||||
r17 -= asr(r21, r31)
|
||||
# CHECK: 51 df 95 cc
|
||||
r17 -= lsr(r21, r31)
|
||||
# CHECK: 91 df 95 cc
|
||||
r17 -= asl(r21, r31)
|
||||
# CHECK: d1 df 95 cc
|
||||
r17 -= lsl(r21, r31)
|
||||
# CHECK: 11 df d5 cc
|
||||
r17 += asr(r21, r31)
|
||||
# CHECK: 51 df d5 cc
|
||||
r17 += lsr(r21, r31)
|
||||
# CHECK: 91 df d5 cc
|
||||
r17 += asl(r21, r31)
|
||||
# CHECK: d1 df d5 cc
|
||||
r17 += lsl(r21, r31)
|
||||
|
||||
# Shift by register and logical
|
||||
# CHECK: 10 df 14 cb
|
||||
r17:16 |= asr(r21:20, r31)
|
||||
# CHECK: 50 df 14 cb
|
||||
r17:16 |= lsr(r21:20, r31)
|
||||
# CHECK: 90 df 14 cb
|
||||
r17:16 |= asl(r21:20, r31)
|
||||
# CHECK: d0 df 14 cb
|
||||
r17:16 |= lsl(r21:20, r31)
|
||||
# CHECK: 10 df 54 cb
|
||||
r17:16 &= asr(r21:20, r31)
|
||||
# CHECK: 50 df 54 cb
|
||||
r17:16 &= lsr(r21:20, r31)
|
||||
# CHECK: 90 df 54 cb
|
||||
r17:16 &= asl(r21:20, r31)
|
||||
# CHECK: d0 df 54 cb
|
||||
r17:16 &= lsl(r21:20, r31)
|
||||
# CHECK: 10 df 74 cb
|
||||
r17:16 ^= asr(r21:20, r31)
|
||||
# CHECK: 50 df 74 cb
|
||||
r17:16 ^= lsr(r21:20, r31)
|
||||
# CHECK: 90 df 74 cb
|
||||
r17:16 ^= asl(r21:20, r31)
|
||||
# CHECK: d0 df 74 cb
|
||||
r17:16 ^= lsl(r21:20, r31)
|
||||
# CHECK: 11 df 15 cc
|
||||
r17 |= asr(r21, r31)
|
||||
# CHECK: 51 df 15 cc
|
||||
r17 |= lsr(r21, r31)
|
||||
# CHECK: 91 df 15 cc
|
||||
r17 |= asl(r21, r31)
|
||||
# CHECK: d1 df 15 cc
|
||||
r17 |= lsl(r21, r31)
|
||||
# CHECK: 11 df 55 cc
|
||||
r17 &= asr(r21, r31)
|
||||
# CHECK: 51 df 55 cc
|
||||
r17 &= lsr(r21, r31)
|
||||
# CHECK: 91 df 55 cc
|
||||
r17 &= asl(r21, r31)
|
||||
# CHECK: d1 df 55 cc
|
||||
r17 &= lsl(r21, r31)
|
||||
|
||||
# Shift by register with saturation
|
||||
# CHECK: 11 df 15 c6
|
||||
r17 = asr(r21, r31):sat
|
||||
# CHECK: 91 df 15 c6
|
||||
r17 = asl(r21, r31):sat
|
||||
|
||||
# Vector shift halfwords by immediate
|
||||
# CHECK: 10 c5 94 80
|
||||
r17:16 = vasrh(r21:20, #5)
|
||||
# CHECK: 30 c5 94 80
|
||||
r17:16 = vlsrh(r21:20, #5)
|
||||
# CHECK: 50 c5 94 80
|
||||
r17:16 = vaslh(r21:20, #5)
|
||||
|
||||
# Vector arithmetic shift halfwords with round
|
||||
# CHECK: 10 c5 34 80
|
||||
r17:16 = vasrh(r21:20, #5):raw
|
||||
|
||||
# Vector arithmetic shift halfwords with saturate and pack
|
||||
# CHECK: 91 c5 74 88
|
||||
r17 = vasrhub(r21:20, #5):raw
|
||||
# CHECK: b1 c5 74 88
|
||||
r17 = vasrhub(r21:20, #5):sat
|
||||
|
||||
# Vector shift halfwords by register
|
||||
# CHECK: 10 df 54 c3
|
||||
r17:16 = vasrh(r21:20, r31)
|
||||
# CHECK: 50 df 54 c3
|
||||
r17:16 = vlsrh(r21:20, r31)
|
||||
# CHECK: 90 df 54 c3
|
||||
r17:16 = vaslh(r21:20, r31)
|
||||
# CHECK: d0 df 54 c3
|
||||
r17:16 = vlslh(r21:20, r31)
|
||||
|
||||
# Vector shift words by immediate
|
||||
# CHECK: 10 df 54 80
|
||||
r17:16 = vasrw(r21:20, #31)
|
||||
# CHECK: 30 df 54 80
|
||||
r17:16 = vlsrw(r21:20, #31)
|
||||
# CHECK: 50 df 54 80
|
||||
r17:16 = vaslw(r21:20, #31)
|
||||
|
||||
# Vector shift words by register
|
||||
# CHECK: 10 df 14 c3
|
||||
r17:16 = vasrw(r21:20, r31)
|
||||
# CHECK: 50 df 14 c3
|
||||
r17:16 = vlsrw(r21:20, r31)
|
||||
# CHECK: 90 df 14 c3
|
||||
r17:16 = vaslw(r21:20, r31)
|
||||
# CHECK: d0 df 14 c3
|
||||
r17:16 = vlslw(r21:20, r31)
|
||||
|
||||
# Vector shift words with truncate and pack
|
||||
# CHECK: 51 df d4 88
|
||||
r17 = vasrw(r21:20, #31)
|
||||
# CHECK: 51 df 14 c5
|
||||
r17 = vasrw(r21:20, r31)
|
Loading…
x
Reference in New Issue
Block a user