<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.naplespu.com/doc/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Francesco</id>
		<title>NaplesPU Documentation - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://www.naplespu.com/doc/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Francesco"/>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=Special:Contributions/Francesco"/>
		<updated>2026-10-14T15:38:24Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.29.1</generator>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=Extending_NaplesPU_for_OpenCL_support&amp;diff=2160</id>
		<title>Extending NaplesPU for OpenCL support</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=Extending_NaplesPU_for_OpenCL_support&amp;diff=2160"/>
				<updated>2019-06-21T15:24:27Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This section describes how the OpenCL C kernel compilation is supported in the NaplesPU toolchain.&lt;br /&gt;
Since Clang natively supports the IR generation of OpenCL C kernels, our work focused on the adaption of the generated code on the NaplesPU core. As the NaplesPU start routine requires to jump to the ''main'' label after having initialized all necessary resources, it is necessary to build a custom optimization pass, to auto-generate the main-function and to define the calling frame to the kernel function. Also OpenCL requires the implementation of custom libraries, extending the ''libc'' set.&lt;br /&gt;
&lt;br /&gt;
== LLVM IR Optimization ==&lt;br /&gt;
&lt;br /&gt;
An IR optimization can be of two different types:&lt;br /&gt;
* Analysis, does not provide a modification of the intermediate representation;&lt;br /&gt;
* Transform, produces a modified IR as output. &lt;br /&gt;
&lt;br /&gt;
LLVM provides an API to create a new optimization pass, hierarchically implemented on the ''Pass'' Class from which the following ones inherit:&lt;br /&gt;
* ModulePass: it is the most general pass. It allows the whole module and the function of which it is composed to be checked. &lt;br /&gt;
* FunctionPass: it allows functions defined in all modules (except for the external ones) to be managed without pursuing a specific order. Functions cannot be deleted.&lt;br /&gt;
* BasicBlockPass: it allows basic blocks to be managed. A basic block can be modified but not removed.&lt;br /&gt;
 &lt;br /&gt;
As a consequence of the classification provided above, for our purpose, the definition of a ModulePass is the most suitable choice.&lt;br /&gt;
&lt;br /&gt;
To write a custom module pass, it is necessary to define a new class by inheriting the ModulePass one and overriding the ''runOnModule()'' method. It contains the code that is executed at each LLVM per-module optimization. If the defined pass modifies the IR, the ''runOnModule'' function returns a ''true'' value. Otherwise, it returns a ''false'' value. As previously discussed, the custom pass should create the ''main'' function by parsing the arguments from the ''argv'' field, and then by calling the kernel function with the right parameters. &lt;br /&gt;
&lt;br /&gt;
The generated code should be of the form as described below.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
; Function Attrs: nounwind&lt;br /&gt;
define void @main(i32, i8** nocapture readonly) local_unnamed_addr #0 {&lt;br /&gt;
  %3 = bitcast i8** %1 to i32*&lt;br /&gt;
  %4 = load i32, i32* %3, align 4&lt;br /&gt;
  ...&lt;br /&gt;
  tail call void @kernel_f(i32 %4, ...) #2&lt;br /&gt;
  ret void&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a consequence, the ModulePass should be structured in the following points:&lt;br /&gt;
&lt;br /&gt;
* Definition of the main function signature:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
FunctionType *main_type = &lt;br /&gt;
TypeBuilder&amp;lt;void(int, char**), false&amp;gt;::get(ctx);&lt;br /&gt;
Function *func = &lt;br /&gt;
cast&amp;lt;Function&amp;gt;(M.getOrInsertFunction(&amp;quot;main&amp;quot;, main_type));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
*Creation of an ''entry'' labeled basic block:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
BasicBlock *block = BasicBlock::Create(ctx, &amp;quot;entry&amp;quot;, func, 0);&lt;br /&gt;
builder.SetInsertPoint(block);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For each kernel argument, create an aligned load instruction to retrieve the argument from the ''argv'' array and add it to the kernel arguments:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
argument_list[counter] = builder.CreateLoad(arg.getType(),&lt;br /&gt;
	builder.CreateBitCast(builder.CreateGEP(&amp;amp;argv, &lt;br /&gt;
	builder.getInt32(index)), &lt;br /&gt;
	arg.getType()-&amp;gt;getPointerTo()));&lt;br /&gt;
argument_list[counter]-&amp;gt;setAlignment(4);&lt;br /&gt;
kernel_arguments.push_back(argument_list[counter++]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Kernel function call:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
builder.CreateCall(kernel_function, kernel_arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Once the pass is defined, the next step consists to register the pass in the ''PassManager'' to add it to the IR optimization pipeline.&lt;br /&gt;
LLVM provides a set of macros that are to be used to initialize the pass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
INITIALIZE_PASS_BEGIN(...)&lt;br /&gt;
INITIALIZE_PASS_END(...)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and to define the pass dependencies:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
INITIALIZE_PASS_DEPENDENCIES(...)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pass initialization must be linked through the ''InitializePasses.h'' header file, in which the following function has to be defined:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
void initialize&amp;lt;PassName&amp;gt;Pass(PassRegistry &amp;amp;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, the specific ModulePass constructor must be declared in the ''LinkAllPasses.h'' header file.&lt;br /&gt;
&lt;br /&gt;
By following these steps, the optimization pass created is automatically chained to the ''opt'' tool pipeline. Moreover, it is useful to automatically execute the pass in each ''clang'' compilation. In order to realize the desired behaviour, the code generation step has to be modified. Clang provides the ''EmitAssemblyHelper::CreatePasses'' method to add a pass to the [[PassManager]].&lt;br /&gt;
&lt;br /&gt;
As an example, consider the following trivial OpenCL kernel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
__kernel void kernel_function(unsigned param,&lt;br /&gt;
  __global unsigned* out)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
 unsigned int i = 0;&lt;br /&gt;
 *out = i + param;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optimization pass creates the main function as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
define void @main(i32, i8** nocapture readonly) local_unnamed_addr #1 {&lt;br /&gt;
entry:&lt;br /&gt;
  %2 = getelementptr i8*, i8** %1, i64 6&lt;br /&gt;
  %3 = bitcast i8** %2 to i32*&lt;br /&gt;
  %4 = load i32, i32* %3, align 4&lt;br /&gt;
  %5 = getelementptr i8*, i8** %1, i64 7&lt;br /&gt;
  %6 = bitcast i8** %5 to i32**&lt;br /&gt;
  %7 = load i32*, i32** %6, align 4&lt;br /&gt;
  tail call void @kernel_function(i32 %4, i32* %7)&lt;br /&gt;
  ret void&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a result, the NaplesPU processor is now capable to run OpenCL kernels.&lt;br /&gt;
&lt;br /&gt;
== Library Extensions ==&lt;br /&gt;
OpenCL provides a set of vector types to explicitly support the lock-step execution. Since NaplesPU is internally structured in a set of hardware lanes, the natively supported vector types are the following:&lt;br /&gt;
&lt;br /&gt;
* ''char16'', ''uchar16'' are respectively mapped on ''vec16i8'' and ''vec16u8'';&lt;br /&gt;
* ''short16'' , ''ushort16'' are respectively mapped on ''vec16i16'' and ''vec16i32''	&lt;br /&gt;
* ''int16'', ''uint16'' are respectively mapped on ''vec16i32'' and ''vec16u32'';&lt;br /&gt;
* ''float16'' is mapped on ''vec16f32''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The OpenCL support for these vector types is provided by adapting the compiler standard library. The adaption involves the modification of the stdint.h library, by adding the lines below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef char char16 __attribute__((ext_vector_type(16)));&lt;br /&gt;
typedef unsigned char uchar16 __attribute__((ext_vector_type(16)));&lt;br /&gt;
typedef short short16 __attribute__((ext_vector_type(16)));&lt;br /&gt;
typedef unsigned short ushort16 __attribute__((ext_vector_type(16)));&lt;br /&gt;
typedef int int16 __attribute__((ext_vector_type(16)));&lt;br /&gt;
typedef unsigned int uint16 __attribute__((ext_vector_type(16)));&lt;br /&gt;
typedef float float16 __attribute__((ext_vector_type(16)));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OpenCL supports a set of builtins used by work-items to retrieve several pieces of information about the enqueued kernel, such as work-item local and global IDs, index space sizes and so on.&lt;br /&gt;
The implementation of these functions relies on the target builtins to obtain information stored on platform registers.&lt;br /&gt;
For instance, take a look to the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
#define WORK_DIM 1&lt;br /&gt;
&lt;br /&gt;
uint get_work_dim () {&lt;br /&gt;
 return WORK_DIM; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint get_local_id(uint dimindx){&lt;br /&gt;
 return __builtin_NaplesPU_read_control_reg(LOCAL_ID);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint get_global_id(uint dimindx){&lt;br /&gt;
 return __builtin_NaplesPU_read_control_reg(GLOBAL_ID);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint get_group_id(uint dimindx){&lt;br /&gt;
 return __builtin_NaplesPU_read_control_reg(CORE_ID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As it is exposed, the work-item builtins implementation maps on NaplesPU builtins, in order to read the control register containing the desired value. Also take note of the WORK_DIM macro, statically defined as 1, because of the hardware constraints.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=Extending_NaplesPU_for_64-bit_support&amp;diff=2159</id>
		<title>Extending NaplesPU for 64-bit support</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=Extending_NaplesPU_for_64-bit_support&amp;diff=2159"/>
				<updated>2019-06-21T15:23:30Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NaplesPU toolchain can be extended to support 64-bit operations. &lt;br /&gt;
A git branch with full 64-bit support is provided. Consequently, if it is necessary to compile the toolchain supporting this extension, a ''checkout'' on ''llvm-7-64b'' branch is required.&lt;br /&gt;
&lt;br /&gt;
Changes are related to both [[NaplesPU Clang Documentation | frontend]] and [[NaplesPU LLVM Documentation | backend]]. &lt;br /&gt;
&lt;br /&gt;
== NaplesPU Frontend Modifications ==&lt;br /&gt;
&lt;br /&gt;
NaplesPU frontend abstracts target informations through the ''TargetInfo'' class, extending it in the [[NaplesPU Clang Documentation #Defining Target Features | NaplesPUTargetInfo]] implementation.&lt;br /&gt;
&lt;br /&gt;
Since 64-bit operations require to support double-integer and double-floating-point formats, the following changes and additions are required in the target definition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 class LLVM_LIBRARY_VISIBILITY NaplesPUTargetInfo : public TargetInfo {&lt;br /&gt;
   ...&lt;br /&gt;
 public:&lt;br /&gt;
   NaplesPUTargetInfo(const llvm::Triple &amp;amp;Triple, const TargetOptions &amp;amp;Opts)&lt;br /&gt;
     : TargetInfo(Triple) {&lt;br /&gt;
     ...&lt;br /&gt;
     resetDataLayout(&amp;quot;e-m:e-p:32:32-i64:64:64-i32:32:32-f32:32:32-f64:64:64&amp;quot;);&lt;br /&gt;
     LongDoubleWidth = 64;&lt;br /&gt;
     LongDoubleAlign = 64;&lt;br /&gt;
     DoubleWidth = 64;&lt;br /&gt;
     DoubleAlign = 64;&lt;br /&gt;
     LongWidth = 64;&lt;br /&gt;
     LongAlign = 64;&lt;br /&gt;
     LongLongWidth = 64;&lt;br /&gt;
     LongLongAlign = 64;&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== NaplesPU Backend Modifications ==&lt;br /&gt;
&lt;br /&gt;
This section describes the backend modification to be applied for 64-bit support.&lt;br /&gt;
&lt;br /&gt;
=== Registers Definition === &lt;br /&gt;
The 64-bit support for registers is based on the &amp;quot;Sub-Reg&amp;quot; behaviour. Since NaplesPU registers are 32-bit wide, a 64-bit variable is stored split in two parts:&lt;br /&gt;
* The higher 32-bit are placed in the S[i] register;&lt;br /&gt;
* The lower 32-bit are placed in the S[i+1] register.&lt;br /&gt;
&lt;br /&gt;
The following class is declared in [[NaplesPURegisterInfo.td]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 class NaplesPU64GPRReg&amp;lt;bits&amp;lt;16&amp;gt; Enc, string n, list&amp;lt;Register&amp;gt; subregs&amp;gt;&lt;br /&gt;
   : NaplesPURegWithSubRegs&amp;lt;Enc, n, subregs&amp;gt; {&lt;br /&gt;
   let SubRegIndices = [sub_even, sub_odd];&lt;br /&gt;
   let CoveredBySubRegs = 1;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The register instantiation is realized as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 foreach i = 0-28 in {&lt;br /&gt;
 def S#!shl(i, 1)#_S#!add(!shl(i, 1), 1) : NaplesPU64GPRReg&amp;lt;!shl(i, 1), &amp;quot;s&amp;quot;#!shl(i, 1)#_64,&lt;br /&gt;
              [!cast&amp;lt;NaplesPUGPRReg&amp;gt;(&amp;quot;S&amp;quot;#!shl(i, 1)),&lt;br /&gt;
              !cast&amp;lt;NaplesPUGPRReg&amp;gt;(&amp;quot;S&amp;quot;#!add(!shl(i, 1), 1))]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the newly defined 64-bit support, it is possible to manage vector registers partitioned in eight cells, in which each one is 64-bit wide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def VR512L : RegisterClass&amp;lt;&amp;quot;NaplesPU&amp;quot;, [v8i64, v8f64, v8i8, v8i16, v8i32], 512, (sequence &amp;quot;V%u&amp;quot;, 0, 63)&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling Convention ===&lt;br /&gt;
Calling conventions for NaplesPU are modified supporting the 64-bit registers. As a result, the [[NaplesPU LLVM Documentation #Calling Convention | 32-bit Calling Convention]] is extended by adding the following lines:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
CCIfType&amp;lt;[v8i8, v8i16, v8i32], CCPromoteToType&amp;lt;v8i64&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[i64, f64], CCAssignToReg&amp;lt;[S0_S1, S2_S3, S4_S5, S6_S7, S8_S9,       S10_S11, S12_S13, S14_S15]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[v16i32, v16f32, v8i64, v8f64], CCAssignToReg&amp;lt;[V0, V1, V2, V3, V4,  V5, V6, V7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The lines above describes how parameters are passed through registers. Also the stack assignment is described below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   CCIfType&amp;lt;[i64, f64], CCAssignToStack&amp;lt;8, 8&amp;gt;&amp;gt;,&lt;br /&gt;
   CCIfType&amp;lt;[v16i32, v16f32, v8i64, v8f64], CCAssignToStack&amp;lt;64, 64&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return value calling convention is extended follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 CCIfType&amp;lt;[i64, f64], CCAssignToReg&amp;lt;[S0_S1, S2_S3, S4_S5, S6_S7, S8_S9, S10_S11]&amp;gt;&amp;gt;,&lt;br /&gt;
 CCIfType&amp;lt;[v8i8, v8i16, v8i32], CCPromoteToType&amp;lt;v8i64&amp;gt;&amp;gt;,&lt;br /&gt;
 CCIfType&amp;lt;[v16i32, v16f32, v8i64, v8f64], CCAssignToReg&amp;lt;[V0, V1, V2, V3, V4, V5]&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ISA Support ===&lt;br /&gt;
&lt;br /&gt;
Referring to [[NaplesPU LLVM Documentation #ISA Support | 32-bit ISA Support]] the 64-bit support on instructions is realized by extending the NaplesPU instruction hierarchy, adding a bit that acts as a mark.&lt;br /&gt;
&lt;br /&gt;
As an example, in the following code, the bit &amp;lt;FR_TwoOp_Unmasked_64&amp;gt; class is derived from the &amp;lt;FR_TwoOp_Unmasked&amp;gt;, setting the sixth parameter as &amp;lt;1&amp;gt;. Recalling what described in the [[NaplesPU LLVM Documentation #ISA Support | 32-bit ISA Support]], it describes if the instruction refers to a 64-bit behaviour or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class FR_TwoOp_Unmasked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
: FR_TwoOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1, fmt0&amp;gt; {}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Instruction Lowering ===&lt;br /&gt;
Since new instructions are defined, a ''lowering'' behaviour on them is often required. As a result, [[NaplesPUISelLowering.cpp | NaplesPUISelLowering]] is extended in some points. For instance, since ''LoadI64'' is a pseudo-instruction, it must be expanded as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
case NaplesPU::LoadI64:&lt;br /&gt;
  return EmitLoadI64(&amp;amp;MI, BB);&lt;br /&gt;
...&lt;br /&gt;
MachineBasicBlock *&lt;br /&gt;
 NaplesPUTargetLowering::EmitLoadI64(MachineInstr *MI,&lt;br /&gt;
                                   MachineBasicBlock *BB) const {&lt;br /&gt;
 &lt;br /&gt;
   DebugLoc DL = MI-&amp;gt;getDebugLoc();&lt;br /&gt;
   const TargetInstrInfo *TII = Subtarget.getInstrInfo();&lt;br /&gt;
   MachineRegisterInfo &amp;amp;MRI = BB-&amp;gt;getParent()-&amp;gt;getRegInfo();&lt;br /&gt;
 &lt;br /&gt;
   // Create the destination register&lt;br /&gt;
   unsigned DstReg = MI-&amp;gt;getOperand(0).getReg();&lt;br /&gt;
   int64_t ImmOp = MI-&amp;gt;getOperand(1).getImm();&lt;br /&gt;
 &lt;br /&gt;
   unsigned Immediate = ((ImmOp &amp;gt;&amp;gt; 32) &amp;amp; 0xffffffff);&lt;br /&gt;
 &lt;br /&gt;
   BuildMI(*BB, MI, DL, TII-&amp;gt;get(NaplesPU::MOVEIHSI))&lt;br /&gt;
               .addReg(DstReg, RegState::Define, NaplesPU::sub_odd)&lt;br /&gt;
               .addImm(((Immediate &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF));&lt;br /&gt;
   BuildMI(*BB, MI, DL, TII-&amp;gt;get(NaplesPU::MOVEILSI))&lt;br /&gt;
               .addReg(DstReg, 0, NaplesPU::sub_odd)&lt;br /&gt;
               .addImm((Immediate &amp;amp; 0xFFFF));&lt;br /&gt;
 &lt;br /&gt;
   Immediate = (ImmOp &amp;amp; 0xffffffff);&lt;br /&gt;
&lt;br /&gt;
   BuildMI(*BB, MI, DL, TII-&amp;gt;get(NaplesPU::MOVEIHSI))&lt;br /&gt;
               .addReg(DstReg, 0, NaplesPU::sub_even)&lt;br /&gt;
               .addImm(((Immediate &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF));&lt;br /&gt;
   BuildMI(*BB, MI, DL, TII-&amp;gt;get(NaplesPU::MOVEILSI))&lt;br /&gt;
               .addReg(DstReg, 0, NaplesPU::sub_even)&lt;br /&gt;
               .addImm((Immediate &amp;amp; 0xFFFF));&lt;br /&gt;
 &lt;br /&gt;
   MI-&amp;gt;eraseFromParent();&lt;br /&gt;
 &lt;br /&gt;
   return BB;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As it is explained, the load operation for 64-bit immediate value is realized by requiring a ''NaplesPU64GPR'' register and writing the split parts on the sub-registers.&lt;br /&gt;
&lt;br /&gt;
=== Disassembler Support ===&lt;br /&gt;
Since new register classes are introduced, proper decode methods are implemented in '''NaplesPUDisassembler'''. As a result, ''DecodeGPR64RegisterClasses'' and ''DecodeVR512LRegisterClasses'' are added to disassemble the code.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_Libraries&amp;diff=2158</id>
		<title>NaplesPU Libraries</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_Libraries&amp;diff=2158"/>
				<updated>2019-06-21T15:22:50Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NaplesPU is provided with different kind of libraries that are contained in the libs/ folder. &lt;br /&gt;
&lt;br /&gt;
== libc ==&lt;br /&gt;
We implemented our custom version of the following standard C libraries:&lt;br /&gt;
* ctype&lt;br /&gt;
* math&lt;br /&gt;
* stdlib&lt;br /&gt;
* string&lt;br /&gt;
&lt;br /&gt;
Note that these libraries are not fully developed and, hence, some functions may be missing. In particular, dynamic memory management (calloc, free, malloc, realloc) and environment (abort, atexit, at_quick_exit, exit, getenv, quick_exit, system) functions are not implemented. In addition, we redefined the stdint.h header file in order to provide a set of typedefs that specify vector types.&lt;br /&gt;
&lt;br /&gt;
During compilation, these libraries are archived together into a single file, i.e. libc.a, using the llvm-ar archiver.&lt;br /&gt;
&lt;br /&gt;
== libcompiler ==&lt;br /&gt;
This folder contains the libraries that are required by the compiler to handle some arithmetic operations that are not legal in the target architecture. In particular, we implemented the following libraries:&lt;br /&gt;
* divdi3.c: signed 64-bit integer division&lt;br /&gt;
* divsi3.c: signed 32-bit integer division&lt;br /&gt;
* moddi3.c: signed 64-bit integer modulus&lt;br /&gt;
* modsi3.c: signed 32-bit integer modulus&lt;br /&gt;
* udivdi3.c: unsigned 64-bit integer division&lt;br /&gt;
* udivsi3.c: unsigned 32-bit integer division&lt;br /&gt;
* umoddi3.c: unsigned 64-bit integer modulus&lt;br /&gt;
* umodsi3.c: unsigned 32-bit integer modulus&lt;br /&gt;
A proper lib call is generated when lowering the following node types:&lt;br /&gt;
*ISD::UDIV&lt;br /&gt;
*ISD::UREM&lt;br /&gt;
*ISD::SDIV&lt;br /&gt;
*ISD::SREM&lt;br /&gt;
This happends because the setOperationAction for the above nodes are set to ''Expand'' inside the [[NaplesPUISelLowering_class | NaplesPUISelLowering.cpp]] file.&lt;br /&gt;
&lt;br /&gt;
== isr==&lt;br /&gt;
This folder contains the NaplesPU Interrupt Service Routines (ISRs). In the current version we have just a single isr, i.e. isr0, which implements an endless loop.&lt;br /&gt;
&lt;br /&gt;
== vectors.s ==&lt;br /&gt;
This assembler file contains the Interrupt Vector Jump Table. Jump operations to the different ISRs are stored in consecutive 32-bit locations. Since, in the current version we have just a single isr, there is only one jump operations.&lt;br /&gt;
&lt;br /&gt;
== crt0.s ==&lt;br /&gt;
This file contains a set of execution startup routines that performs any initialization work required before calling the program's main function. The main steps are:&lt;br /&gt;
# Loading the stack/frame pointers from the stack table that is located at the end of the file. The stack table is filled with the addresses of the different stacks that are defined inside the [[LinkerScript | linker script]]. The current version supports eight threads for each core. The offset inside the stack_table is calculated as i*32+j*4, where ''i'' is the core ID and j is the thread ID. In case of an higher number of threads, it is required to change both the crt0.o and the [[LinkerScript | linker script]].&lt;br /&gt;
# Thread 0 of Core 0 performs constructor startup required for the initialization of C/C++ objects. This is done by calling the functions that are located inside the .init_array section.&lt;br /&gt;
# Threads 0 of each core performs scratchpad preload initialization. This is done using first vector loads/stores, then 64-bit scalar loads/stores and finally 32-bit scalar loads/stores.&lt;br /&gt;
# The argc and argv arguments are put inside the s0 and s1 registers according to the NaplesPU [[NaplesPUCallingConv.td | calling convention]].&lt;br /&gt;
# All hardware lanes are enabled by default.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_Libraries&amp;diff=2157</id>
		<title>NaplesPU Libraries</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_Libraries&amp;diff=2157"/>
				<updated>2019-06-21T15:22:31Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NuPlus is provided with different kind of libraries that are contained in the libs/ folder. &lt;br /&gt;
&lt;br /&gt;
== libc ==&lt;br /&gt;
We implemented our custom version of the following standard C libraries:&lt;br /&gt;
* ctype&lt;br /&gt;
* math&lt;br /&gt;
* stdlib&lt;br /&gt;
* string&lt;br /&gt;
&lt;br /&gt;
Note that these libraries are not fully developed and, hence, some functions may be missing. In particular, dynamic memory management (calloc, free, malloc, realloc) and environment (abort, atexit, at_quick_exit, exit, getenv, quick_exit, system) functions are not implemented. In addition, we redefined the stdint.h header file in order to provide a set of typedefs that specify vector types.&lt;br /&gt;
&lt;br /&gt;
During compilation, these libraries are archived together into a single file, i.e. libc.a, using the llvm-ar archiver.&lt;br /&gt;
&lt;br /&gt;
== libcompiler ==&lt;br /&gt;
This folder contains the libraries that are required by the compiler to handle some arithmetic operations that are not legal in the target architecture. In particular, we implemented the following libraries:&lt;br /&gt;
* divdi3.c: signed 64-bit integer division&lt;br /&gt;
* divsi3.c: signed 32-bit integer division&lt;br /&gt;
* moddi3.c: signed 64-bit integer modulus&lt;br /&gt;
* modsi3.c: signed 32-bit integer modulus&lt;br /&gt;
* udivdi3.c: unsigned 64-bit integer division&lt;br /&gt;
* udivsi3.c: unsigned 32-bit integer division&lt;br /&gt;
* umoddi3.c: unsigned 64-bit integer modulus&lt;br /&gt;
* umodsi3.c: unsigned 32-bit integer modulus&lt;br /&gt;
A proper lib call is generated when lowering the following node types:&lt;br /&gt;
*ISD::UDIV&lt;br /&gt;
*ISD::UREM&lt;br /&gt;
*ISD::SDIV&lt;br /&gt;
*ISD::SREM&lt;br /&gt;
This happends because the setOperationAction for the above nodes are set to ''Expand'' inside the [[NuPlusISelLowering_class | NuPlusISelLowering.cpp]] file.&lt;br /&gt;
&lt;br /&gt;
== isr==&lt;br /&gt;
This folder contains the nu+ Interrupt Service Routines (ISRs). In the current version we have just a single isr, i.e. isr0, which implements an endless loop.&lt;br /&gt;
&lt;br /&gt;
== vectors.s ==&lt;br /&gt;
This assembler file contains the Interrupt Vector Jump Table. Jump operations to the different ISRs are stored in consecutive 32-bit locations. Since, in the current version we have just a single isr, there is only one jump operations.&lt;br /&gt;
&lt;br /&gt;
== crt0.s ==&lt;br /&gt;
This file contains a set of execution startup routines that performs any initialization work required before calling the program's main function. The main steps are:&lt;br /&gt;
# Loading the stack/frame pointers from the stack table that is located at the end of the file. The stack table is filled with the addresses of the different stacks that are defined inside the [[LinkerScript | linker script]]. The current version supports eight threads for each core. The offset inside the stack_table is calculated as i*32+j*4, where ''i'' is the core ID and j is the thread ID. In case of an higher number of threads, it is required to change both the crt0.o and the [[LinkerScript | linker script]].&lt;br /&gt;
# Thread 0 of Core 0 performs constructor startup required for the initialization of C/C++ objects. This is done by calling the functions that are located inside the .init_array section.&lt;br /&gt;
# Threads 0 of each core performs scratchpad preload initialization. This is done using first vector loads/stores, then 64-bit scalar loads/stores and finally 32-bit scalar loads/stores.&lt;br /&gt;
# The argc and argv arguments are put inside the s0 and s1 registers according to the nu+ [[NuPlusCallingConv.td | calling convention]].&lt;br /&gt;
# All hardware lanes are enabled by default.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_Libraries&amp;diff=2156</id>
		<title>NaplesPU Libraries</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_Libraries&amp;diff=2156"/>
				<updated>2019-06-21T15:22:26Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NaplesPU is provided with different kind of libraries that are contained in the libs/ folder. &lt;br /&gt;
&lt;br /&gt;
== libc ==&lt;br /&gt;
We implemented our custom version of the following standard C libraries:&lt;br /&gt;
* ctype&lt;br /&gt;
* math&lt;br /&gt;
* stdlib&lt;br /&gt;
* string&lt;br /&gt;
&lt;br /&gt;
Note that these libraries are not fully developed and, hence, some functions may be missing. In particular, dynamic memory management (calloc, free, malloc, realloc) and environment (abort, atexit, at_quick_exit, exit, getenv, quick_exit, system) functions are not implemented. In addition, we redefined the stdint.h header file in order to provide a set of typedefs that specify vector types.&lt;br /&gt;
&lt;br /&gt;
During compilation, these libraries are archived together into a single file, i.e. libc.a, using the llvm-ar archiver.&lt;br /&gt;
&lt;br /&gt;
== libcompiler ==&lt;br /&gt;
This folder contains the libraries that are required by the compiler to handle some arithmetic operations that are not legal in the target architecture. In particular, we implemented the following libraries:&lt;br /&gt;
* divdi3.c: signed 64-bit integer division&lt;br /&gt;
* divsi3.c: signed 32-bit integer division&lt;br /&gt;
* moddi3.c: signed 64-bit integer modulus&lt;br /&gt;
* modsi3.c: signed 32-bit integer modulus&lt;br /&gt;
* udivdi3.c: unsigned 64-bit integer division&lt;br /&gt;
* udivsi3.c: unsigned 32-bit integer division&lt;br /&gt;
* umoddi3.c: unsigned 64-bit integer modulus&lt;br /&gt;
* umodsi3.c: unsigned 32-bit integer modulus&lt;br /&gt;
A proper lib call is generated when lowering the following node types:&lt;br /&gt;
*ISD::UDIV&lt;br /&gt;
*ISD::UREM&lt;br /&gt;
*ISD::SDIV&lt;br /&gt;
*ISD::SREM&lt;br /&gt;
This happends because the setOperationAction for the above nodes are set to ''Expand'' inside the [[NaplesPUISelLowering_class | NaplesPUISelLowering.cpp]] file.&lt;br /&gt;
&lt;br /&gt;
== isr==&lt;br /&gt;
This folder contains the NaplesPU Interrupt Service Routines (ISRs). In the current version we have just a single isr, i.e. isr0, which implements an endless loop.&lt;br /&gt;
&lt;br /&gt;
== vectors.s ==&lt;br /&gt;
This assembler file contains the Interrupt Vector Jump Table. Jump operations to the different ISRs are stored in consecutive 32-bit locations. Since, in the current version we have just a single isr, there is only one jump operations.&lt;br /&gt;
&lt;br /&gt;
== crt0.s ==&lt;br /&gt;
This file contains a set of execution startup routines that performs any initialization work required before calling the program's main function. The main steps are:&lt;br /&gt;
# Loading the stack/frame pointers from the stack table that is located at the end of the file. The stack table is filled with the addresses of the different stacks that are defined inside the [[LinkerScript | linker script]]. The current version supports eight threads for each core. The offset inside the stack_table is calculated as i*32+j*4, where ''i'' is the core ID and j is the thread ID. In case of an higher number of threads, it is required to change both the crt0.o and the [[LinkerScript | linker script]].&lt;br /&gt;
# Thread 0 of Core 0 performs constructor startup required for the initialization of C/C++ objects. This is done by calling the functions that are located inside the .init_array section.&lt;br /&gt;
# Threads 0 of each core performs scratchpad preload initialization. This is done using first vector loads/stores, then 64-bit scalar loads/stores and finally 32-bit scalar loads/stores.&lt;br /&gt;
# The argc and argv arguments are put inside the s0 and s1 registers according to the NaplesPU [[NaplesPUCallingConv.td | calling convention]].&lt;br /&gt;
# All hardware lanes are enabled by default.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_Libraries&amp;diff=2154</id>
		<title>NaplesPU Libraries</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_Libraries&amp;diff=2154"/>
				<updated>2019-06-21T15:22:09Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page Nu+ Libraries to NaplesPU Libraries&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NuPlus is provided with different kind of libraries that are contained in the libs/ folder. &lt;br /&gt;
&lt;br /&gt;
== libc ==&lt;br /&gt;
We implemented our custom version of the following standard C libraries:&lt;br /&gt;
* ctype&lt;br /&gt;
* math&lt;br /&gt;
* stdlib&lt;br /&gt;
* string&lt;br /&gt;
&lt;br /&gt;
Note that these libraries are not fully developed and, hence, some functions may be missing. In particular, dynamic memory management (calloc, free, malloc, realloc) and environment (abort, atexit, at_quick_exit, exit, getenv, quick_exit, system) functions are not implemented. In addition, we redefined the stdint.h header file in order to provide a set of typedefs that specify vector types.&lt;br /&gt;
&lt;br /&gt;
During compilation, these libraries are archived together into a single file, i.e. libc.a, using the llvm-ar archiver.&lt;br /&gt;
&lt;br /&gt;
== libcompiler ==&lt;br /&gt;
This folder contains the libraries that are required by the compiler to handle some arithmetic operations that are not legal in the target architecture. In particular, we implemented the following libraries:&lt;br /&gt;
* divdi3.c: signed 64-bit integer division&lt;br /&gt;
* divsi3.c: signed 32-bit integer division&lt;br /&gt;
* moddi3.c: signed 64-bit integer modulus&lt;br /&gt;
* modsi3.c: signed 32-bit integer modulus&lt;br /&gt;
* udivdi3.c: unsigned 64-bit integer division&lt;br /&gt;
* udivsi3.c: unsigned 32-bit integer division&lt;br /&gt;
* umoddi3.c: unsigned 64-bit integer modulus&lt;br /&gt;
* umodsi3.c: unsigned 32-bit integer modulus&lt;br /&gt;
A proper lib call is generated when lowering the following node types:&lt;br /&gt;
*ISD::UDIV&lt;br /&gt;
*ISD::UREM&lt;br /&gt;
*ISD::SDIV&lt;br /&gt;
*ISD::SREM&lt;br /&gt;
This happends because the setOperationAction for the above nodes are set to ''Expand'' inside the [[NuPlusISelLowering_class | NuPlusISelLowering.cpp]] file.&lt;br /&gt;
&lt;br /&gt;
== isr==&lt;br /&gt;
This folder contains the nu+ Interrupt Service Routines (ISRs). In the current version we have just a single isr, i.e. isr0, which implements an endless loop.&lt;br /&gt;
&lt;br /&gt;
== vectors.s ==&lt;br /&gt;
This assembler file contains the Interrupt Vector Jump Table. Jump operations to the different ISRs are stored in consecutive 32-bit locations. Since, in the current version we have just a single isr, there is only one jump operations.&lt;br /&gt;
&lt;br /&gt;
== crt0.s ==&lt;br /&gt;
This file contains a set of execution startup routines that performs any initialization work required before calling the program's main function. The main steps are:&lt;br /&gt;
# Loading the stack/frame pointers from the stack table that is located at the end of the file. The stack table is filled with the addresses of the different stacks that are defined inside the [[LinkerScript | linker script]]. The current version supports eight threads for each core. The offset inside the stack_table is calculated as i*32+j*4, where ''i'' is the core ID and j is the thread ID. In case of an higher number of threads, it is required to change both the crt0.o and the [[LinkerScript | linker script]].&lt;br /&gt;
# Thread 0 of Core 0 performs constructor startup required for the initialization of C/C++ objects. This is done by calling the functions that are located inside the .init_array section.&lt;br /&gt;
# Threads 0 of each core performs scratchpad preload initialization. This is done using first vector loads/stores, then 64-bit scalar loads/stores and finally 32-bit scalar loads/stores.&lt;br /&gt;
# The argc and argv arguments are put inside the s0 and s1 registers according to the nu+ [[NuPlusCallingConv.td | calling convention]].&lt;br /&gt;
# All hardware lanes are enabled by default.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=Nu%2B_Libraries&amp;diff=2155</id>
		<title>Nu+ Libraries</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=Nu%2B_Libraries&amp;diff=2155"/>
				<updated>2019-06-21T15:22:09Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page Nu+ Libraries to NaplesPU Libraries&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPU Libraries]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_Tools&amp;diff=2153</id>
		<title>NaplesPU Tools</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_Tools&amp;diff=2153"/>
				<updated>2019-06-21T15:22:01Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NaplesPU is provided with a set of additional tools in order to fully support the compilation process of an application. &lt;br /&gt;
&lt;br /&gt;
== elf2hex ==&lt;br /&gt;
elf2hex is the tool required for elf code transformation. It works on an input ELF code to produce a hex output file as the memory image to be written on device memory. NaplesPU relies on its own implementation of the elf2hex tool, located in elf2hex.cpp. In our purposes, the tool produces two different outputs:&lt;br /&gt;
* MANGO compliant memory image, a 512-bit little-endian aligned image ready to be flashed on the MANGO platform;&lt;br /&gt;
* Standalone compliant memory image, a 512-bit little-endian aligned image to be used in a standalone environment.&lt;br /&gt;
&lt;br /&gt;
== Disassembler == &lt;br /&gt;
A disassembler attempts to revert back the assembly code from the binary one. In order to be able to support NaplesPU code disassembly, LLVM requires to implement a Disassembler class. The implementation is provided in [[NaplesPUDisassembler.cpp]]. Disassembly methods rely on auto-generated ''decoder tables'' from TableGen files. TableGen also offers a way to force a specific decoder method to be called, specifying the ''DecoderMethod'' field on instructions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def V16MEMri : Operand&amp;lt;v16i32&amp;gt; {&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeMemoryOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeVectorWMemoryOpValue&amp;quot;;&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static DecodeStatus decodeVectorWMemoryOpValue(...) &lt;br /&gt;
{&lt;br /&gt;
  return decodeMemoryOpValue(Inst, Insn, Address, Decoder,&lt;br /&gt;
         NaplesPU::VR512WRegClassID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object File Dumper ==&lt;br /&gt;
LLVM provides a custom tool to work as an object file dumper, that is a utility that prints the contents of object files and of the final linked image. For this reason, it is primarily used to debug the generated machine code. In the LLVM implementation, the ''llvm-objdump'' binary relies on the Disassembler classes, in order to revert the binary code into the assembly back.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=Nu%2B_Tools&amp;diff=2152</id>
		<title>Nu+ Tools</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=Nu%2B_Tools&amp;diff=2152"/>
				<updated>2019-06-21T15:21:35Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page Nu+ Tools to NaplesPU Tools&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPU Tools]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_Tools&amp;diff=2151</id>
		<title>NaplesPU Tools</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_Tools&amp;diff=2151"/>
				<updated>2019-06-21T15:21:35Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page Nu+ Tools to NaplesPU Tools&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;nu+ is provided with a set of additional tools in order to fully support the compilation process of an application. &lt;br /&gt;
&lt;br /&gt;
== elf2hex ==&lt;br /&gt;
elf2hex is the tool required for elf code transformation. It works on an input ELF code to produce a hex output file as the memory image to be written on device memory. nu+ relies on its own implementation of the elf2hex tool, located in elf2hex.cpp. In our purposes, the tool produces two different outputs:&lt;br /&gt;
* MANGO compliant memory image, a 512-bit little-endian aligned image ready to be flashed on the MANGO platform;&lt;br /&gt;
* Standalone compliant memory image, a 512-bit little-endian aligned image to be used in a standalone environment.&lt;br /&gt;
&lt;br /&gt;
== Disassembler == &lt;br /&gt;
A disassembler attempts to revert back the assembly code from the binary one. In order to be able to support nu+ code disassembly, LLVM requires to implement a Disassembler class. The implementation is provided in [[NuPlusDisassembler.cpp]]. Disassembly methods rely on auto-generated ''decoder tables'' from TableGen files. TableGen also offers a way to force a specific decoder method to be called, specifying the ''DecoderMethod'' field on instructions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def V16MEMri : Operand&amp;lt;v16i32&amp;gt; {&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeMemoryOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeVectorWMemoryOpValue&amp;quot;;&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static DecodeStatus decodeVectorWMemoryOpValue(...) &lt;br /&gt;
{&lt;br /&gt;
  return decodeMemoryOpValue(Inst, Insn, Address, Decoder,&lt;br /&gt;
         NuPlus::VR512WRegClassID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object File Dumper ==&lt;br /&gt;
LLVM provides a custom tool to work as an object file dumper, that is a utility that prints the contents of object files and of the final linked image. For this reason, it is primarily used to debug the generated machine code. In the LLVM implementation, the ''llvm-objdump'' binary relies on the Disassembler classes, in order to revert the binary code into the assembly back.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_LLD_Linker&amp;diff=2150</id>
		<title>NaplesPU LLD Linker</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_LLD_Linker&amp;diff=2150"/>
				<updated>2019-06-21T15:21:17Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LLD is the LLVM proprietary linker. It is based on the GNU linker, and it is compatible to it in terms of arguments accepted. It also fully supports the ''ELF'' generation but also, in a progressive lower percentage, ''PE/COFF'', ''Mach-O'', ''WebAssembly'' and custom linker-scripts.&lt;br /&gt;
LLD is built as a set of libraries to join the main idea of the software modular design.&lt;br /&gt;
&lt;br /&gt;
The NaplesPU implementation of LLD is made on an ELF-based approach, by adding a new Target class inside lld/ELF/Arch folder. [[NaplesPU.cpp]] contains the ''relocation'' logic and other information needed to support NaplesPU. Each NaplesPU application must be linked together with two additional object files:&lt;br /&gt;
&lt;br /&gt;
* ''crt0.o'', is the object file resulting of the compilation of the start routine for the custom platform, composed of operations needed to set-up the platform. &lt;br /&gt;
* ''vectors.o'', is the Interrupt Vector Table.&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
This section explains how the relocations are implemented in NaplesPU.  &lt;br /&gt;
All relocations are specified in the ''relocateOne'' method implementation. By looking at the target ISA, LLD must check for each instruction type in which an immediate value is specified to verify if it can fit the machine instruction field.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
void NaplesPU::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {&lt;br /&gt;
  int64_t Offset;&lt;br /&gt;
  switch (Type) {&lt;br /&gt;
  default:&lt;br /&gt;
    fatal(&amp;quot;unrecognized reloc &amp;quot; + Twine(Type));&lt;br /&gt;
    case R_NUPLUS_ABS32:&lt;br /&gt;
     write32le(Loc, Val);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_BRANCH:&lt;br /&gt;
     //Check Offset for J-Type Instructions&lt;br /&gt;
     checkInt(Loc, Val, 18, Type);&lt;br /&gt;
     applyNaplesPUReloc&amp;lt;18, 0&amp;gt;(Loc, Type, Val);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_PCREL_MEM:&lt;br /&gt;
     //Check Offset for M-Type Instructions&lt;br /&gt;
     checkInt(Loc, Val, 9, Type);&lt;br /&gt;
     applyNaplesPUReloc&amp;lt;9, 3&amp;gt;(Loc, Type, Val);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_PCREL_LEA:&lt;br /&gt;
     //Check Offset for I-Type Instructions&lt;br /&gt;
     checkInt(Loc, Val, 9, Type);&lt;br /&gt;
     applyNaplesPUReloc&amp;lt;9, 3&amp;gt;(Loc, Type, Val);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_ABS_HIGH_LEA:&lt;br /&gt;
     //Check Offset for MOVEI-Type Instructions&lt;br /&gt;
     checkInt(Loc, (Val &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF , 16, Type);&lt;br /&gt;
     applyNaplesPUReloc&amp;lt;16, 2&amp;gt;(Loc, Type, (Val &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_ABS_LOW_LEA:&lt;br /&gt;
     //Check Offset for MOVEI-Type Instructions&lt;br /&gt;
     checkInt(Loc, (Val) &amp;amp; 0xFFFF , 16, Type);&lt;br /&gt;
     applyNaplesPUReloc&amp;lt;16, 2&amp;gt;(Loc, Type, (Val) &amp;amp; 0xFFFF);&lt;br /&gt;
     break;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All of these implemented relocations relies on the method ''applyNaplesPURelocation'' that simply writes back the value into the instruction.&lt;br /&gt;
&lt;br /&gt;
== Linkerscript ==&lt;br /&gt;
&lt;br /&gt;
All memory images generated for NaplesPU must be linked in a proper way. This way is specified by the linkerscript:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
stacks_dim = 16K;&lt;br /&gt;
stacks_base = 0x80000;&lt;br /&gt;
threads_per_core = 0x8;&lt;br /&gt;
&lt;br /&gt;
SECTIONS&lt;br /&gt;
{&lt;br /&gt;
  . = 0x00000380;&lt;br /&gt;
  .text.vectors : {&lt;br /&gt;
    *vectors.o(.text)&lt;br /&gt;
    . = 0x00000400;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .text.start : {&lt;br /&gt;
    *crt0.o(.text)&lt;br /&gt;
  }&lt;br /&gt;
  .text : { *(.text) }&lt;br /&gt;
&lt;br /&gt;
  . = 0x00800000;&lt;br /&gt;
  .data : { *(.data) }&lt;br /&gt;
&lt;br /&gt;
  . = ALIGN(64);&lt;br /&gt;
  scratchpad : { *(scratchpad) }&lt;br /&gt;
&lt;br /&gt;
  .bss : { *(.bss) }&lt;br /&gt;
&lt;br /&gt;
  .eh_frame : { *(.eh_frame) }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As shown above, the linker script commonly defines where the sections must be placed into the memory. Also, it solves undefined symbols of the start routine, specifying the stack size per-thread, the number of threads and the starting address for the stack frame.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_LLD_Linker&amp;diff=2147</id>
		<title>NaplesPU LLD Linker</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_LLD_Linker&amp;diff=2147"/>
				<updated>2019-06-21T15:20:46Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page Nu+ LLD Linker to NaplesPU LLD Linker&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LLD is the LLVM proprietary linker. It is based on the GNU linker, and it is compatible to it in terms of arguments accepted. It also fully supports the ''ELF'' generation but also, in a progressive lower percentage, ''PE/COFF'', ''Mach-O'', ''WebAssembly'' and custom linker-scripts.&lt;br /&gt;
LLD is built as a set of libraries to join the main idea of the software modular design.&lt;br /&gt;
&lt;br /&gt;
The nu+ implementation of LLD is made on an ELF-based approach, by adding a new Target class inside lld/ELF/Arch folder. [[NuPlus.cpp]] contains the ''relocation'' logic and other information needed to support nu+. Each nu+ application must be linked together with two additional object files:&lt;br /&gt;
&lt;br /&gt;
* ''crt0.o'', is the object file resulting of the compilation of the start routine for the custom platform, composed of operations needed to set-up the platform. &lt;br /&gt;
* ''vectors.o'', is the Interrupt Vector Table.&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
This section explains how the relocations are implemented in nu+.  &lt;br /&gt;
All relocations are specified in the ''relocateOne'' method implementation. By looking at the target ISA, LLD must check for each instruction type in which an immediate value is specified to verify if it can fit the machine instruction field.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
void NuPlus::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {&lt;br /&gt;
  int64_t Offset;&lt;br /&gt;
  switch (Type) {&lt;br /&gt;
  default:&lt;br /&gt;
    fatal(&amp;quot;unrecognized reloc &amp;quot; + Twine(Type));&lt;br /&gt;
    case R_NUPLUS_ABS32:&lt;br /&gt;
     write32le(Loc, Val);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_BRANCH:&lt;br /&gt;
     //Check Offset for J-Type Instructions&lt;br /&gt;
     checkInt(Loc, Val, 18, Type);&lt;br /&gt;
     applyNuPlusReloc&amp;lt;18, 0&amp;gt;(Loc, Type, Val);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_PCREL_MEM:&lt;br /&gt;
     //Check Offset for M-Type Instructions&lt;br /&gt;
     checkInt(Loc, Val, 9, Type);&lt;br /&gt;
     applyNuPlusReloc&amp;lt;9, 3&amp;gt;(Loc, Type, Val);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_PCREL_LEA:&lt;br /&gt;
     //Check Offset for I-Type Instructions&lt;br /&gt;
     checkInt(Loc, Val, 9, Type);&lt;br /&gt;
     applyNuPlusReloc&amp;lt;9, 3&amp;gt;(Loc, Type, Val);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_ABS_HIGH_LEA:&lt;br /&gt;
     //Check Offset for MOVEI-Type Instructions&lt;br /&gt;
     checkInt(Loc, (Val &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF , 16, Type);&lt;br /&gt;
     applyNuPlusReloc&amp;lt;16, 2&amp;gt;(Loc, Type, (Val &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF);&lt;br /&gt;
     break;&lt;br /&gt;
   case R_NUPLUS_ABS_LOW_LEA:&lt;br /&gt;
     //Check Offset for MOVEI-Type Instructions&lt;br /&gt;
     checkInt(Loc, (Val) &amp;amp; 0xFFFF , 16, Type);&lt;br /&gt;
     applyNuPlusReloc&amp;lt;16, 2&amp;gt;(Loc, Type, (Val) &amp;amp; 0xFFFF);&lt;br /&gt;
     break;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All of these implemented relocations relies on the method ''applyNuPlusRelocation'' that simply writes back the value into the instruction.&lt;br /&gt;
&lt;br /&gt;
== Linkerscript ==&lt;br /&gt;
&lt;br /&gt;
All memory images generated for nu+ must be linked in a proper way. This way is specified by the linkerscript:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
stacks_dim = 16K;&lt;br /&gt;
stacks_base = 0x80000;&lt;br /&gt;
threads_per_core = 0x8;&lt;br /&gt;
&lt;br /&gt;
SECTIONS&lt;br /&gt;
{&lt;br /&gt;
  . = 0x00000380;&lt;br /&gt;
  .text.vectors : {&lt;br /&gt;
    *vectors.o(.text)&lt;br /&gt;
    . = 0x00000400;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .text.start : {&lt;br /&gt;
    *crt0.o(.text)&lt;br /&gt;
  }&lt;br /&gt;
  .text : { *(.text) }&lt;br /&gt;
&lt;br /&gt;
  . = 0x00800000;&lt;br /&gt;
  .data : { *(.data) }&lt;br /&gt;
&lt;br /&gt;
  . = ALIGN(64);&lt;br /&gt;
  scratchpad : { *(scratchpad) }&lt;br /&gt;
&lt;br /&gt;
  .bss : { *(.bss) }&lt;br /&gt;
&lt;br /&gt;
  .eh_frame : { *(.eh_frame) }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As shown above, the linker script commonly defines where the sections must be placed into the memory. Also, it solves undefined symbols of the start routine, specifying the stack size per-thread, the number of threads and the starting address for the stack frame.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=Nu%2B_LLD_Linker&amp;diff=2148</id>
		<title>Nu+ LLD Linker</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=Nu%2B_LLD_Linker&amp;diff=2148"/>
				<updated>2019-06-21T15:20:46Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page Nu+ LLD Linker to NaplesPU LLD Linker&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPU LLD Linker]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUMCInstLower.cpp&amp;diff=2143</id>
		<title>NaplesPUMCInstLower.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUMCInstLower.cpp&amp;diff=2143"/>
				<updated>2019-06-21T15:05:53Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The NaplesPUMCInstLower class transforms the MachineInstr object into a simplified version, the MCInst one. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NaplesPUMCInstLower.cpp - Convert NaplesPU MachineInstr to MCInst -------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This file contains code to lower NaplesPU MachineInstrs to their corresponding&lt;br /&gt;
// MCInst records.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NaplesPUAsmPrinter.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NaplesPUInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NaplesPUMCInstLower.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineFunction.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineInstr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineOperand.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCContext.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCExpr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInst.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSymbol.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define GET_REGINFO_ENUM&lt;br /&gt;
#include &amp;quot;NaplesPUGenRegisterInfo.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
NaplesPUMCInstLower::NaplesPUMCInstLower(NaplesPUAsmPrinter &amp;amp;asmprinter)&lt;br /&gt;
  : AsmPrinter(asmprinter) {}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUMCInstLower::Initialize(MCContext *C) {&lt;br /&gt;
  Ctx = C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Derived from MipsMCInstLower&lt;br /&gt;
MCOperand NaplesPUMCInstLower::LowerSymbolOperand(const MachineOperand &amp;amp;MO,&lt;br /&gt;
                                              MachineOperandType MOTy,&lt;br /&gt;
                                              unsigned Offset) const {&lt;br /&gt;
  MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;&lt;br /&gt;
  const MCSymbol *Symbol;&lt;br /&gt;
&lt;br /&gt;
  switch (MOTy) {&lt;br /&gt;
  case MachineOperand::MO_MachineBasicBlock:&lt;br /&gt;
    Symbol = MO.getMBB()-&amp;gt;getSymbol();&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  case MachineOperand::MO_GlobalAddress:&lt;br /&gt;
    Symbol = AsmPrinter.getSymbol(MO.getGlobal());&lt;br /&gt;
    Offset += MO.getOffset();&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  case MachineOperand::MO_BlockAddress:&lt;br /&gt;
    Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());&lt;br /&gt;
    Offset += MO.getOffset();&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  case MachineOperand::MO_ExternalSymbol:&lt;br /&gt;
    Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());&lt;br /&gt;
    Offset += MO.getOffset();&lt;br /&gt;
    break;&lt;br /&gt;
  case MachineOperand::MO_JumpTableIndex:&lt;br /&gt;
    Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());&lt;br /&gt;
    break;&lt;br /&gt;
  case MachineOperand::MO_ConstantPoolIndex:&lt;br /&gt;
    Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());&lt;br /&gt;
    Offset += MO.getOffset();&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  default:&lt;br /&gt;
    llvm_unreachable(&amp;quot;&amp;lt;unknown operand type&amp;gt;&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //TODO: controllare differenze con MIPS e come mai nel case manca MO_MCSymbol (anche nella funzione successiva)&lt;br /&gt;
  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);&lt;br /&gt;
  if (!Offset)&lt;br /&gt;
    return MCOperand::createExpr(MCSym);&lt;br /&gt;
&lt;br /&gt;
  // Assume offset is never negative.&lt;br /&gt;
  assert(Offset &amp;gt; 0);&lt;br /&gt;
  const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx);&lt;br /&gt;
  const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);&lt;br /&gt;
  return MCOperand::createExpr(Add);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
MCOperand NaplesPUMCInstLower::LowerOperand(const MachineOperand &amp;amp;MO,&lt;br /&gt;
                                        unsigned offset) const {&lt;br /&gt;
  MachineOperandType MOTy = MO.getType();&lt;br /&gt;
&lt;br /&gt;
  switch (MOTy) {&lt;br /&gt;
  default: llvm_unreachable(&amp;quot;unknown operand type&amp;quot;);&lt;br /&gt;
  case MachineOperand::MO_Register:&lt;br /&gt;
    // Ignore all implicit register operands.&lt;br /&gt;
    if (MO.isImplicit()) break;&lt;br /&gt;
    return MCOperand::createReg(MO.getReg());&lt;br /&gt;
  case MachineOperand::MO_Immediate:&lt;br /&gt;
    return MCOperand::createImm(MO.getImm() + offset);&lt;br /&gt;
  case MachineOperand::MO_MachineBasicBlock:&lt;br /&gt;
  case MachineOperand::MO_GlobalAddress:&lt;br /&gt;
  case MachineOperand::MO_ExternalSymbol:&lt;br /&gt;
  case MachineOperand::MO_JumpTableIndex:&lt;br /&gt;
  case MachineOperand::MO_ConstantPoolIndex:&lt;br /&gt;
  case MachineOperand::MO_BlockAddress:&lt;br /&gt;
    return LowerSymbolOperand(MO, MOTy, offset);&lt;br /&gt;
  case MachineOperand::MO_RegisterMask:&lt;br /&gt;
    break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
  return MCOperand();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void NaplesPUMCInstLower::Lower(const MachineInstr *MI, MCInst &amp;amp;OutMI) const {&lt;br /&gt;
  OutMI.setOpcode(MI-&amp;gt;getOpcode());&lt;br /&gt;
&lt;br /&gt;
  // XXX note that this chunk of code assumes a load instruction. It's also&lt;br /&gt;
  // possible for MO_ConstantPoolIndex to appear in arithmetic.  In this&lt;br /&gt;
  // situation, the instruction would be clobbered.&lt;br /&gt;
  //TODO: questo if usato nel caso in cui l'istruzione usa costantpool o jumptable. &lt;br /&gt;
  // noi non abbiamo la jump table. E la costant pool?? controllare e modificare&lt;br /&gt;
  if (MI-&amp;gt;getNumOperands() &amp;gt; 1 &amp;amp;&amp;amp;&lt;br /&gt;
      (MI-&amp;gt;getOperand(1).getType() == MachineOperand::MO_ConstantPoolIndex ||&lt;br /&gt;
       MI-&amp;gt;getOperand(1).getType() == MachineOperand::MO_JumpTableIndex)) {&lt;br /&gt;
    OutMI.addOperand(LowerOperand(MI-&amp;gt;getOperand(0))); // result&lt;br /&gt;
&lt;br /&gt;
    const MachineOperand &amp;amp;cpEntry = MI-&amp;gt;getOperand(1);&lt;br /&gt;
&lt;br /&gt;
    // This is a PC relative constant pool access.  Add the PC register&lt;br /&gt;
    // to this instruction to match what the assembly parser produces&lt;br /&gt;
    // (and InstPrinter/Encoder expects)&lt;br /&gt;
    // It should look like this:&lt;br /&gt;
    // &amp;lt;MCInst #97 LWi &amp;lt;MCOperand Reg:8&amp;gt; &amp;lt;MCOperand Reg:3&amp;gt; &amp;lt;MCOperand&lt;br /&gt;
    // Expr:(foo)&amp;gt;&amp;gt;&lt;br /&gt;
    OutMI.addOperand(MCOperand::createReg(NaplesPU::PC_REG));&lt;br /&gt;
    const MCSymbol *Symbol;&lt;br /&gt;
    if (MI-&amp;gt;getOperand(1).getType() == MachineOperand::MO_ConstantPoolIndex)&lt;br /&gt;
      Symbol = AsmPrinter.GetCPISymbol(cpEntry.getIndex());&lt;br /&gt;
    else&lt;br /&gt;
      Symbol = AsmPrinter.GetJTISymbol(cpEntry.getIndex());&lt;br /&gt;
&lt;br /&gt;
    const MCSymbolRefExpr *MCSym =&lt;br /&gt;
        MCSymbolRefExpr::create(Symbol, MCSymbolRefExpr::VK_None, *Ctx);&lt;br /&gt;
    MCOperand MCOp = MCOperand::createExpr(MCSym);&lt;br /&gt;
    OutMI.addOperand(MCOp);&lt;br /&gt;
  } else {&lt;br /&gt;
    for (unsigned i = 0, e = MI-&amp;gt;getNumOperands(); i != e; ++i) {&lt;br /&gt;
      const MachineOperand &amp;amp;MO = MI-&amp;gt;getOperand(i);&lt;br /&gt;
      MCOperand MCOp = LowerOperand(MO);&lt;br /&gt;
&lt;br /&gt;
      if (MCOp.isValid())&lt;br /&gt;
        OutMI.addOperand(MCOp);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUMCCodeEmitter.cpp&amp;diff=2141</id>
		<title>NaplesPUMCCodeEmitter.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUMCCodeEmitter.cpp&amp;diff=2141"/>
				<updated>2019-06-21T15:05:33Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NaplesPUMCCodeEmitter class transforms MCInst objects into binary code representation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NaplesPUMCCodeEmitter.cpp - Convert NaplesPU code to machine code -------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This file implements the NaplesPUMCCodeEmitter class.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NaplesPUFixupKinds.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NaplesPUMCTargetDesc.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/ADT/Statistic.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCCodeEmitter.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCContext.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCExpr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCFixup.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInst.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCRegisterInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSubtargetInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSymbol.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#define DEBUG_TYPE &amp;quot;mccodeemitter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STATISTIC(MCNumEmitted, &amp;quot;Number of MC instructions emitted&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
namespace {&lt;br /&gt;
class NaplesPUMCCodeEmitter : public MCCodeEmitter {&lt;br /&gt;
  NaplesPUMCCodeEmitter(const NaplesPUMCCodeEmitter &amp;amp;) = delete;&lt;br /&gt;
  void operator=(const NaplesPUMCCodeEmitter &amp;amp;) = delete;&lt;br /&gt;
  MCContext &amp;amp;Ctx;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
  NaplesPUMCCodeEmitter(const MCInstrInfo &amp;amp;mcii, MCContext &amp;amp;ctx): Ctx(ctx) {}&lt;br /&gt;
&lt;br /&gt;
  // getBinaryCodeForInstr - TableGen'erated function for getting the&lt;br /&gt;
  // binary encoding for an instruction.&lt;br /&gt;
  uint64_t getBinaryCodeForInstr(const MCInst &amp;amp;MI,&lt;br /&gt;
                                 SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                 const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
&lt;br /&gt;
  /// getMachineOpValue - Return binary encoding of operand. If the machine&lt;br /&gt;
  /// operand requires relocation, record the relocation and return zero.&lt;br /&gt;
  unsigned getMachineOpValue(const MCInst &amp;amp;MI, const MCOperand &amp;amp;MO,&lt;br /&gt;
                             SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                             const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
&lt;br /&gt;
  void encodeInstruction(const MCInst &amp;amp;MI, raw_ostream &amp;amp;OS,&lt;br /&gt;
                         SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                         const MCSubtargetInfo &amp;amp;STI) const override;&lt;br /&gt;
&lt;br /&gt;
  unsigned encodeMemoryOpValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                               SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                               const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
&lt;br /&gt;
  unsigned encodeLEAValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                          SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                          const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
&lt;br /&gt;
  unsigned encodeABShValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                          SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                          const MCSubtargetInfo &amp;amp;STI) const; &lt;br /&gt;
&lt;br /&gt;
  unsigned encodeABSlValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                          SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                          const MCSubtargetInfo &amp;amp;STI) const;                        &lt;br /&gt;
&lt;br /&gt;
  unsigned encodeBranchTargetOpValue(const MCInst &amp;amp;MI, unsigned OpNo,&lt;br /&gt;
                                     SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                     const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
  &lt;br /&gt;
  // Emit one byte through output stream (from MCBlazeMCCodeEmitter)&lt;br /&gt;
  void EmitByte(unsigned char C, raw_ostream &amp;amp;OS) const { OS &amp;lt;&amp;lt; (char)C; }&lt;br /&gt;
&lt;br /&gt;
  void EmitLEConstant(uint64_t Val, unsigned Size, raw_ostream &amp;amp;OS) const {&lt;br /&gt;
    assert(Size &amp;lt;= 8 &amp;amp;&amp;amp; &amp;quot;size too big in emit constant&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (unsigned i = 0; i != Size; ++i) {&lt;br /&gt;
      EmitByte(Val &amp;amp; 255, OS);&lt;br /&gt;
      Val &amp;gt;&amp;gt;= 8;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
} // end anonymous namespace&lt;br /&gt;
&lt;br /&gt;
MCCodeEmitter *llvm::createNaplesPUMCCodeEmitter(const MCInstrInfo &amp;amp;MCII,&lt;br /&gt;
                                              const MCRegisterInfo &amp;amp;MRI,&lt;br /&gt;
                                              MCContext &amp;amp;Ctx) {&lt;br /&gt;
  return new NaplesPUMCCodeEmitter(MCII, Ctx);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return binary encoding of operand.&lt;br /&gt;
unsigned NaplesPUMCCodeEmitter::&lt;br /&gt;
getMachineOpValue(const MCInst &amp;amp;MI, const MCOperand &amp;amp;MO,&lt;br /&gt;
                  SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                  const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
&lt;br /&gt;
  if (MO.isReg())&lt;br /&gt;
    return Ctx.getRegisterInfo()-&amp;gt;getEncodingValue(MO.getReg());&lt;br /&gt;
&lt;br /&gt;
  if (MO.isImm())&lt;br /&gt;
    return static_cast&amp;lt;unsigned&amp;gt;(MO.getImm());&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUMCCodeEmitter::encodeInstruction(const MCInst &amp;amp;MI, raw_ostream &amp;amp;OS,&lt;br /&gt;
                                           SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                           const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);&lt;br /&gt;
  EmitLEConstant(Bits, 4, OS);&lt;br /&gt;
&lt;br /&gt;
  ++MCNumEmitted;  // Keep track of the # of mi's emitted.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned NaplesPUMCCodeEmitter::encodeABShValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                                            SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                            const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  // with LEAH the second operand is expected to be the global address&lt;br /&gt;
  //MCOperand address = MI.getOperand(1);&lt;br /&gt;
  // the third operand is the label used in the asm&lt;br /&gt;
  //MCOperand address_asm = MI.getOperand(2);&lt;br /&gt;
&lt;br /&gt;
  if (MI.getOperand(1).isExpr()) {&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0, MI.getOperand(1).getExpr(),&lt;br /&gt;
        MCFixupKind(NaplesPU::fixup_NaplesPU_Absh)));&lt;br /&gt;
  } else if ( MI.getOperand(2).isExpr()) {&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0,  MI.getOperand(2).getExpr(),&lt;br /&gt;
        MCFixupKind(NaplesPU::fixup_NaplesPU_Absh)));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned NaplesPUMCCodeEmitter::encodeABSlValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                                            SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                            const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  // with LEAH the third operand is expected to be the global address&lt;br /&gt;
  //MCOperand address = MI.getOperand(2);&lt;br /&gt;
  // the fourth operand is the label used in the asm&lt;br /&gt;
  //MCOperand address_asm = MI.getOperand(3);&lt;br /&gt;
&lt;br /&gt;
  if (MI.getOperand(2).isExpr()) {&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0, MI.getOperand(2).getExpr(),&lt;br /&gt;
        MCFixupKind(NaplesPU::fixup_NaplesPU_Absl)));&lt;br /&gt;
  } else if (MI.getOperand(3).isExpr()) {&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0, MI.getOperand(3).getExpr(),&lt;br /&gt;
        MCFixupKind(NaplesPU::fixup_NaplesPU_Absl)));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned NaplesPUMCCodeEmitter::encodeLEAValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                                            SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                            const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  MCOperand baseReg = MI.getOperand(1);&lt;br /&gt;
  MCOperand offsetOp = MI.getOperand(2);&lt;br /&gt;
&lt;br /&gt;
  assert(baseReg.isReg() &amp;amp;&amp;amp; &amp;quot;First operand of LEA op is not register.&amp;quot;);&lt;br /&gt;
  unsigned encoding = Ctx.getRegisterInfo()-&amp;gt;getEncodingValue(baseReg.getReg())&amp;lt;&amp;lt;10;&lt;br /&gt;
  if (offsetOp.isExpr()) {&lt;br /&gt;
    // Load with a label. This is a PC relative load.  Add a fixup.&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0, offsetOp.getExpr(),&lt;br /&gt;
        MCFixupKind(NaplesPU::fixup_NaplesPU_PCRel_Lea)));&lt;br /&gt;
  } else if (offsetOp.isImm())&lt;br /&gt;
    encoding |= static_cast&amp;lt;short&amp;gt;(offsetOp.getImm())&amp;lt;&amp;lt;1;&lt;br /&gt;
  else&lt;br /&gt;
    assert(offsetOp.isImm() &amp;amp;&amp;amp; &amp;quot;Second operand of LEA op is unknown type.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return encoding;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Encode NaplesPU Memory Operand.  The result is a packed field with the&lt;br /&gt;
// register in the low 5 bits and the offset in the remainder.  The instruction&lt;br /&gt;
// patterns will put these into the proper part of the instruction&lt;br /&gt;
// (NaplesPUInstrFormats.td).&lt;br /&gt;
unsigned&lt;br /&gt;
NaplesPUMCCodeEmitter::encodeMemoryOpValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                                        SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                        const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  unsigned encoding;&lt;br /&gt;
&lt;br /&gt;
  MCOperand baseReg;&lt;br /&gt;
  MCOperand offsetOp;&lt;br /&gt;
&lt;br /&gt;
  baseReg = MI.getOperand(1);&lt;br /&gt;
  offsetOp = MI.getOperand(2); &lt;br /&gt;
  &lt;br /&gt;
  // Register&lt;br /&gt;
  // This is register/offset.  No need for relocation.&lt;br /&gt;
  assert(baseReg.isReg() &amp;amp;&amp;amp; &amp;quot;First operand is not register.&amp;quot;);&lt;br /&gt;
  //encoding just the register&lt;br /&gt;
  encoding = Ctx.getRegisterInfo()-&amp;gt;getEncodingValue(baseReg.getReg());&lt;br /&gt;
  // Offset&lt;br /&gt;
  if (offsetOp.isExpr()) {&lt;br /&gt;
    // Load with a label. This is a PC relative load.  Add a fixup.&lt;br /&gt;
    // XXX Note that this assumes unmasked instructions.  A masked&lt;br /&gt;
    // instruction will not work and should not be used. Check for this&lt;br /&gt;
    // and return an error.&lt;br /&gt;
    Fixups.push_back(&lt;br /&gt;
        MCFixup::create(0, offsetOp.getExpr(),&lt;br /&gt;
                        MCFixupKind(NaplesPU::fixup_NaplesPU_PCRel_Mem)));&lt;br /&gt;
  } else if (offsetOp.isImm())&lt;br /&gt;
    encoding |= static_cast&amp;lt;short&amp;gt;(offsetOp.getImm()) &amp;lt;&amp;lt; 6;&lt;br /&gt;
  else&lt;br /&gt;
    assert(offsetOp.isImm() &amp;amp;&amp;amp; &amp;quot;Second operand of memory op is unknown type.&amp;quot;);&lt;br /&gt;
  return encoding;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// encodeBranchTargetOpValue - Return binary encoding of the jump&lt;br /&gt;
// target operand. If the machine operand requires relocation,&lt;br /&gt;
// record the relocation and return zero.&lt;br /&gt;
unsigned NaplesPUMCCodeEmitter::encodeBranchTargetOpValue(&lt;br /&gt;
    const MCInst &amp;amp;MI, unsigned OpNo, SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
    const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
&lt;br /&gt;
  const MCOperand &amp;amp;MO = MI.getOperand(OpNo);&lt;br /&gt;
  if (MO.isImm())&lt;br /&gt;
    return MO.getImm();&lt;br /&gt;
&lt;br /&gt;
  assert(MO.isExpr() &amp;amp;&amp;amp;&lt;br /&gt;
         &amp;quot;encodeBranchTargetOpValue expects only expressions or an immediate&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  const MCExpr *Expr = MO.getExpr();&lt;br /&gt;
  Fixups.push_back(&lt;br /&gt;
      MCFixup::create(0, Expr, MCFixupKind(NaplesPU::fixup_NaplesPU_Branch)));&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NaplesPUGenMCCodeEmitter.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUInstPrinter.cpp&amp;diff=2139</id>
		<title>NaplesPUInstPrinter.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUInstPrinter.cpp&amp;diff=2139"/>
				<updated>2019-06-21T15:05:13Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NaplesPUInstPrinter contains method to print assembly instructions from MCInst objects. &lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NaplesPUInstPrinter.cpp - Convert NaplesPU MCInst to assembly syntax -----==//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This class prints an NaplesPU MCInst to a .s file.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NaplesPUInstPrinter.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NaplesPUMCTargetDesc.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NaplesPUInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/ADT/StringExtras.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCExpr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInst.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCRegisterInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSymbol.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/ErrorHandling.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#define DEBUG_TYPE &amp;quot;asm-printer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NaplesPUGenAsmWriter.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
namespace&lt;br /&gt;
{&lt;br /&gt;
void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,&lt;br /&gt;
               raw_ostream &amp;amp;OS)&lt;br /&gt;
{&lt;br /&gt;
  int Offset = 0;&lt;br /&gt;
  const MCSymbolRefExpr *SRE;&lt;br /&gt;
&lt;br /&gt;
  if (const MCBinaryExpr *BE = dyn_cast&amp;lt;MCBinaryExpr&amp;gt;(Expr))&lt;br /&gt;
  {&lt;br /&gt;
    SRE = dyn_cast&amp;lt;MCSymbolRefExpr&amp;gt;(BE-&amp;gt;getLHS());&lt;br /&gt;
    const MCConstantExpr *CE = dyn_cast&amp;lt;MCConstantExpr&amp;gt;(BE-&amp;gt;getRHS());&lt;br /&gt;
    assert(SRE &amp;amp;&amp;amp; CE &amp;amp;&amp;amp; &amp;quot;Binary expression must be sym+const.&amp;quot;);&lt;br /&gt;
    Offset = CE-&amp;gt;getValue();&lt;br /&gt;
  }&lt;br /&gt;
  else if (!(SRE = dyn_cast&amp;lt;MCSymbolRefExpr&amp;gt;(Expr)))&lt;br /&gt;
  {&lt;br /&gt;
    Expr-&amp;gt;print(OS, MAI);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  MCSymbolRefExpr::VariantKind Kind = SRE-&amp;gt;getKind();&lt;br /&gt;
&lt;br /&gt;
  OS &amp;lt;&amp;lt; SRE-&amp;gt;getSymbol();&lt;br /&gt;
&lt;br /&gt;
  if (Offset)&lt;br /&gt;
  {&lt;br /&gt;
    if (Offset &amp;gt; 0)&lt;br /&gt;
      OS &amp;lt;&amp;lt; '+';&lt;br /&gt;
    OS &amp;lt;&amp;lt; Offset;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (Kind != MCSymbolRefExpr::VK_None)&lt;br /&gt;
    OS &amp;lt;&amp;lt; ')';&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUInstPrinter::printRegName(raw_ostream &amp;amp;OS, unsigned RegNo) const&lt;br /&gt;
{&lt;br /&gt;
  // TODO: (Catello) magic errs()&lt;br /&gt;
  //errs()&amp;lt;&amp;lt; &amp;quot;&amp;quot;;&lt;br /&gt;
  OS &amp;lt;&amp;lt; StringRef(getRegisterName(RegNo)).lower();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUInstPrinter::printInst(const MCInst *MI, raw_ostream &amp;amp;O,&lt;br /&gt;
                                  StringRef Annot, const MCSubtargetInfo &amp;amp;STI)&lt;br /&gt;
{&lt;br /&gt;
  // NOP is or s0, s0, 0&lt;br /&gt;
  if (MI-&amp;gt;getOpcode() == NaplesPU::ORSSI &amp;amp;&amp;amp; MI-&amp;gt;getOperand(0).isReg() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(0).getReg() == NaplesPU::S0 &amp;amp;&amp;amp; MI-&amp;gt;getOperand(1).isReg() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(1).getReg() == NaplesPU::S0 &amp;amp;&amp;amp; MI-&amp;gt;getOperand(2).isImm() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(2).getImm() == 0)&lt;br /&gt;
  {&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;\tnop&amp;quot;;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  printInstruction(MI, O);&lt;br /&gt;
  printAnnotation(O, Annot);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUInstPrinter::printOperand(const MCInst *MI, int opNum,&lt;br /&gt;
                                     raw_ostream &amp;amp;O)&lt;br /&gt;
{&lt;br /&gt;
  const MCOperand &amp;amp;MO = MI-&amp;gt;getOperand(opNum);&lt;br /&gt;
&lt;br /&gt;
  if (MO.isReg())&lt;br /&gt;
  {&lt;br /&gt;
    printRegName(O, MO.getReg());&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (MO.isImm())&lt;br /&gt;
  {&lt;br /&gt;
    O &amp;lt;&amp;lt; (int)MO.getImm();&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  assert(MO.isExpr() &amp;amp;&amp;amp; &amp;quot;Unknown operand kind in printOperand&amp;quot;);&lt;br /&gt;
  if (MO.isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    printExpr(MO.getExpr(), &amp;amp;MAI, O);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUInstPrinter::printMemOperand(const MCInst *MI, int opNum,&lt;br /&gt;
                                        raw_ostream &amp;amp;O)&lt;br /&gt;
{&lt;br /&gt;
   if (MI-&amp;gt;getOperand(opNum).isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    // Abs instructions&lt;br /&gt;
    printOperand(MI, opNum, O);&lt;br /&gt;
  }&lt;br /&gt;
  else if (MI-&amp;gt;getOperand(opNum + 1).isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    // PC relative memory access to a local label&lt;br /&gt;
    printOperand(MI, opNum + 1, O);&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    // Register/offset&lt;br /&gt;
    assert(MI-&amp;gt;getOperand(opNum).isReg());&lt;br /&gt;
    assert(MI-&amp;gt;getOperand(opNum + 1).isImm());&lt;br /&gt;
&lt;br /&gt;
    if (MI-&amp;gt;getOperand(opNum + 1).getImm())&lt;br /&gt;
      printOperand(MI, opNum + 1, O);&lt;br /&gt;
&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;(&amp;quot;;&lt;br /&gt;
    printOperand(MI, opNum, O);&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;)&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUInstPrinter.cpp&amp;diff=2138</id>
		<title>NaplesPUInstPrinter.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUInstPrinter.cpp&amp;diff=2138"/>
				<updated>2019-06-21T15:04:59Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NuPlusInstPrinter contains method to print assembly instructions from MCInst objects. &lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusInstPrinter.cpp - Convert NuPlus MCInst to assembly syntax -----==//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This class prints an NuPlus MCInst to a .s file.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusInstPrinter.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NuPlusMCTargetDesc.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NuPlusInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/ADT/StringExtras.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCExpr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInst.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCRegisterInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSymbol.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/ErrorHandling.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#define DEBUG_TYPE &amp;quot;asm-printer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusGenAsmWriter.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
namespace&lt;br /&gt;
{&lt;br /&gt;
void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,&lt;br /&gt;
               raw_ostream &amp;amp;OS)&lt;br /&gt;
{&lt;br /&gt;
  int Offset = 0;&lt;br /&gt;
  const MCSymbolRefExpr *SRE;&lt;br /&gt;
&lt;br /&gt;
  if (const MCBinaryExpr *BE = dyn_cast&amp;lt;MCBinaryExpr&amp;gt;(Expr))&lt;br /&gt;
  {&lt;br /&gt;
    SRE = dyn_cast&amp;lt;MCSymbolRefExpr&amp;gt;(BE-&amp;gt;getLHS());&lt;br /&gt;
    const MCConstantExpr *CE = dyn_cast&amp;lt;MCConstantExpr&amp;gt;(BE-&amp;gt;getRHS());&lt;br /&gt;
    assert(SRE &amp;amp;&amp;amp; CE &amp;amp;&amp;amp; &amp;quot;Binary expression must be sym+const.&amp;quot;);&lt;br /&gt;
    Offset = CE-&amp;gt;getValue();&lt;br /&gt;
  }&lt;br /&gt;
  else if (!(SRE = dyn_cast&amp;lt;MCSymbolRefExpr&amp;gt;(Expr)))&lt;br /&gt;
  {&lt;br /&gt;
    Expr-&amp;gt;print(OS, MAI);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  MCSymbolRefExpr::VariantKind Kind = SRE-&amp;gt;getKind();&lt;br /&gt;
&lt;br /&gt;
  OS &amp;lt;&amp;lt; SRE-&amp;gt;getSymbol();&lt;br /&gt;
&lt;br /&gt;
  if (Offset)&lt;br /&gt;
  {&lt;br /&gt;
    if (Offset &amp;gt; 0)&lt;br /&gt;
      OS &amp;lt;&amp;lt; '+';&lt;br /&gt;
    OS &amp;lt;&amp;lt; Offset;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (Kind != MCSymbolRefExpr::VK_None)&lt;br /&gt;
    OS &amp;lt;&amp;lt; ')';&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusInstPrinter::printRegName(raw_ostream &amp;amp;OS, unsigned RegNo) const&lt;br /&gt;
{&lt;br /&gt;
  // TODO: (Catello) magic errs()&lt;br /&gt;
  //errs()&amp;lt;&amp;lt; &amp;quot;&amp;quot;;&lt;br /&gt;
  OS &amp;lt;&amp;lt; StringRef(getRegisterName(RegNo)).lower();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusInstPrinter::printInst(const MCInst *MI, raw_ostream &amp;amp;O,&lt;br /&gt;
                                  StringRef Annot, const MCSubtargetInfo &amp;amp;STI)&lt;br /&gt;
{&lt;br /&gt;
  // NOP is or s0, s0, 0&lt;br /&gt;
  if (MI-&amp;gt;getOpcode() == NuPlus::ORSSI &amp;amp;&amp;amp; MI-&amp;gt;getOperand(0).isReg() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(0).getReg() == NuPlus::S0 &amp;amp;&amp;amp; MI-&amp;gt;getOperand(1).isReg() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(1).getReg() == NuPlus::S0 &amp;amp;&amp;amp; MI-&amp;gt;getOperand(2).isImm() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(2).getImm() == 0)&lt;br /&gt;
  {&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;\tnop&amp;quot;;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  printInstruction(MI, O);&lt;br /&gt;
  printAnnotation(O, Annot);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusInstPrinter::printOperand(const MCInst *MI, int opNum,&lt;br /&gt;
                                     raw_ostream &amp;amp;O)&lt;br /&gt;
{&lt;br /&gt;
  const MCOperand &amp;amp;MO = MI-&amp;gt;getOperand(opNum);&lt;br /&gt;
&lt;br /&gt;
  if (MO.isReg())&lt;br /&gt;
  {&lt;br /&gt;
    printRegName(O, MO.getReg());&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (MO.isImm())&lt;br /&gt;
  {&lt;br /&gt;
    O &amp;lt;&amp;lt; (int)MO.getImm();&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  assert(MO.isExpr() &amp;amp;&amp;amp; &amp;quot;Unknown operand kind in printOperand&amp;quot;);&lt;br /&gt;
  if (MO.isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    printExpr(MO.getExpr(), &amp;amp;MAI, O);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusInstPrinter::printMemOperand(const MCInst *MI, int opNum,&lt;br /&gt;
                                        raw_ostream &amp;amp;O)&lt;br /&gt;
{&lt;br /&gt;
   if (MI-&amp;gt;getOperand(opNum).isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    // Abs instructions&lt;br /&gt;
    printOperand(MI, opNum, O);&lt;br /&gt;
  }&lt;br /&gt;
  else if (MI-&amp;gt;getOperand(opNum + 1).isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    // PC relative memory access to a local label&lt;br /&gt;
    printOperand(MI, opNum + 1, O);&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    // Register/offset&lt;br /&gt;
    assert(MI-&amp;gt;getOperand(opNum).isReg());&lt;br /&gt;
    assert(MI-&amp;gt;getOperand(opNum + 1).isImm());&lt;br /&gt;
&lt;br /&gt;
    if (MI-&amp;gt;getOperand(opNum + 1).getImm())&lt;br /&gt;
      printOperand(MI, opNum + 1, O);&lt;br /&gt;
&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;(&amp;quot;;&lt;br /&gt;
    printOperand(MI, opNum, O);&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;)&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUInstPrinter.cpp&amp;diff=2137</id>
		<title>NaplesPUInstPrinter.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUInstPrinter.cpp&amp;diff=2137"/>
				<updated>2019-06-21T15:04:55Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NaplesPUInstPrinter contains method to print assembly instructions from MCInst objects. &lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NaplesPUInstPrinter.cpp - Convert NaplesPU MCInst to assembly syntax -----==//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This class prints an NaplesPU MCInst to a .s file.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NaplesPUInstPrinter.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NaplesPUMCTargetDesc.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NaplesPUInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/ADT/StringExtras.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCExpr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInst.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCRegisterInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSymbol.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/ErrorHandling.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#define DEBUG_TYPE &amp;quot;asm-printer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NaplesPUGenAsmWriter.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
namespace&lt;br /&gt;
{&lt;br /&gt;
void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,&lt;br /&gt;
               raw_ostream &amp;amp;OS)&lt;br /&gt;
{&lt;br /&gt;
  int Offset = 0;&lt;br /&gt;
  const MCSymbolRefExpr *SRE;&lt;br /&gt;
&lt;br /&gt;
  if (const MCBinaryExpr *BE = dyn_cast&amp;lt;MCBinaryExpr&amp;gt;(Expr))&lt;br /&gt;
  {&lt;br /&gt;
    SRE = dyn_cast&amp;lt;MCSymbolRefExpr&amp;gt;(BE-&amp;gt;getLHS());&lt;br /&gt;
    const MCConstantExpr *CE = dyn_cast&amp;lt;MCConstantExpr&amp;gt;(BE-&amp;gt;getRHS());&lt;br /&gt;
    assert(SRE &amp;amp;&amp;amp; CE &amp;amp;&amp;amp; &amp;quot;Binary expression must be sym+const.&amp;quot;);&lt;br /&gt;
    Offset = CE-&amp;gt;getValue();&lt;br /&gt;
  }&lt;br /&gt;
  else if (!(SRE = dyn_cast&amp;lt;MCSymbolRefExpr&amp;gt;(Expr)))&lt;br /&gt;
  {&lt;br /&gt;
    Expr-&amp;gt;print(OS, MAI);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  MCSymbolRefExpr::VariantKind Kind = SRE-&amp;gt;getKind();&lt;br /&gt;
&lt;br /&gt;
  OS &amp;lt;&amp;lt; SRE-&amp;gt;getSymbol();&lt;br /&gt;
&lt;br /&gt;
  if (Offset)&lt;br /&gt;
  {&lt;br /&gt;
    if (Offset &amp;gt; 0)&lt;br /&gt;
      OS &amp;lt;&amp;lt; '+';&lt;br /&gt;
    OS &amp;lt;&amp;lt; Offset;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (Kind != MCSymbolRefExpr::VK_None)&lt;br /&gt;
    OS &amp;lt;&amp;lt; ')';&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUInstPrinter::printRegName(raw_ostream &amp;amp;OS, unsigned RegNo) const&lt;br /&gt;
{&lt;br /&gt;
  // TODO: (Catello) magic errs()&lt;br /&gt;
  //errs()&amp;lt;&amp;lt; &amp;quot;&amp;quot;;&lt;br /&gt;
  OS &amp;lt;&amp;lt; StringRef(getRegisterName(RegNo)).lower();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUInstPrinter::printInst(const MCInst *MI, raw_ostream &amp;amp;O,&lt;br /&gt;
                                  StringRef Annot, const MCSubtargetInfo &amp;amp;STI)&lt;br /&gt;
{&lt;br /&gt;
  // NOP is or s0, s0, 0&lt;br /&gt;
  if (MI-&amp;gt;getOpcode() == NaplesPU::ORSSI &amp;amp;&amp;amp; MI-&amp;gt;getOperand(0).isReg() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(0).getReg() == NaplesPU::S0 &amp;amp;&amp;amp; MI-&amp;gt;getOperand(1).isReg() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(1).getReg() == NaplesPU::S0 &amp;amp;&amp;amp; MI-&amp;gt;getOperand(2).isImm() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(2).getImm() == 0)&lt;br /&gt;
  {&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;\tnop&amp;quot;;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  printInstruction(MI, O);&lt;br /&gt;
  printAnnotation(O, Annot);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUInstPrinter::printOperand(const MCInst *MI, int opNum,&lt;br /&gt;
                                     raw_ostream &amp;amp;O)&lt;br /&gt;
{&lt;br /&gt;
  const MCOperand &amp;amp;MO = MI-&amp;gt;getOperand(opNum);&lt;br /&gt;
&lt;br /&gt;
  if (MO.isReg())&lt;br /&gt;
  {&lt;br /&gt;
    printRegName(O, MO.getReg());&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (MO.isImm())&lt;br /&gt;
  {&lt;br /&gt;
    O &amp;lt;&amp;lt; (int)MO.getImm();&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  assert(MO.isExpr() &amp;amp;&amp;amp; &amp;quot;Unknown operand kind in printOperand&amp;quot;);&lt;br /&gt;
  if (MO.isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    printExpr(MO.getExpr(), &amp;amp;MAI, O);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUInstPrinter::printMemOperand(const MCInst *MI, int opNum,&lt;br /&gt;
                                        raw_ostream &amp;amp;O)&lt;br /&gt;
{&lt;br /&gt;
   if (MI-&amp;gt;getOperand(opNum).isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    // Abs instructions&lt;br /&gt;
    printOperand(MI, opNum, O);&lt;br /&gt;
  }&lt;br /&gt;
  else if (MI-&amp;gt;getOperand(opNum + 1).isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    // PC relative memory access to a local label&lt;br /&gt;
    printOperand(MI, opNum + 1, O);&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    // Register/offset&lt;br /&gt;
    assert(MI-&amp;gt;getOperand(opNum).isReg());&lt;br /&gt;
    assert(MI-&amp;gt;getOperand(opNum + 1).isImm());&lt;br /&gt;
&lt;br /&gt;
    if (MI-&amp;gt;getOperand(opNum + 1).getImm())&lt;br /&gt;
      printOperand(MI, opNum + 1, O);&lt;br /&gt;
&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;(&amp;quot;;&lt;br /&gt;
    printOperand(MI, opNum, O);&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;)&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUISelLowering.cpp&amp;diff=2136</id>
		<title>NaplesPUISelLowering.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUISelLowering.cpp&amp;diff=2136"/>
				<updated>2019-06-21T15:04:14Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=NaplesPUTargetLowering class=&lt;br /&gt;
[[Category:C++ Classes]]&lt;br /&gt;
The '''NaplesPUTargetLowering''' class implements the [http://llvm.org/docs/CodeGenerator.html#the-targetlowering-class TargetLowering] interface and is contained in the NaplesPUISelLowering.h/.cpp files. &lt;br /&gt;
The class must describe how to lower LLVM code to machine code. This has two main components:&lt;br /&gt;
#Which ValueTypes are natively supported by the target.&lt;br /&gt;
#Which operations are supported for supported ValueTypes.&lt;br /&gt;
&lt;br /&gt;
The '''NaplesPUTargetLowering''' class can be thought of being composed by four sections:&lt;br /&gt;
#The class constructor.&lt;br /&gt;
#The custom [https://llvm.org/docs/CodeGenerator.html#introduction-to-selectiondags SDNode] lowering.&lt;br /&gt;
#The custom [http://llvm.org/docs/CodeGenerator.html#machineinstr MachineInstruction] insertion.&lt;br /&gt;
#The implementation of other TargetLowering virtual methods.&lt;br /&gt;
&lt;br /&gt;
== The Class Constructor ==&lt;br /&gt;
The NaplesPUTargetLowering class constructor describes the MachineValueTypes supported by NaplesPU with the corresponding [[NaplesPURegisterInfo.td |RegisterClass]], the operations not supported for supported MachineValueTypes and the corresponding action to perform, other useful information concerning the Instruction-Lowering phase.&lt;br /&gt;
These informations are described using the ''protected'' methods provided by the base class ''TargetLowering''. &lt;br /&gt;
&lt;br /&gt;
=== addRegisterClass ===&lt;br /&gt;
The '''addRegisterClass''' method tells the Code Generator the supported MachineValueTypes and the RegisterClass to use. The '''MachineValueTypes''' are defined in the '''MVT''' class in &amp;quot;compiler/include/llvm/CodeGen/MachineValueType.h&amp;quot;, while the RegisterClass are those defined in [[NaplesPURegisterInfo.td]]. The following table summarize the supported MachineValueTypes and the relative RegisterClass.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;font-weight: bold;&amp;quot; | RegisterClass&lt;br /&gt;
! style=&amp;quot;font-weight: bold;&amp;quot; | MVT&lt;br /&gt;
|-&lt;br /&gt;
| GPR32RegClass&lt;br /&gt;
| i32, f32&lt;br /&gt;
|-&lt;br /&gt;
| GPR64RegClass&lt;br /&gt;
| i64, f64&lt;br /&gt;
|-&lt;br /&gt;
| VR512WRegClass&lt;br /&gt;
| v16i32, v16f32&lt;br /&gt;
|-&lt;br /&gt;
| VR512LRegClass&lt;br /&gt;
| v8i64, v8f64&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The corresponding code is:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
  // Scalar data types&lt;br /&gt;
  addRegisterClass(MVT::i32, &amp;amp;NaplesPU::GPR32RegClass);&lt;br /&gt;
  addRegisterClass(MVT::f32, &amp;amp;NaplesPU::GPR32RegClass);&lt;br /&gt;
&lt;br /&gt;
  addRegisterClass(MVT::i64, &amp;amp;NaplesPU::GPR64RegClass);&lt;br /&gt;
  addRegisterClass(MVT::f64, &amp;amp;NaplesPU::GPR64RegClass);&lt;br /&gt;
&lt;br /&gt;
  // Vector data types (512-bit wide)&lt;br /&gt;
  addRegisterClass(MVT::v16i32, &amp;amp;NaplesPU::VR512WRegClass);&lt;br /&gt;
  addRegisterClass(MVT::v16f32, &amp;amp;NaplesPU::VR512WRegClass);&lt;br /&gt;
&lt;br /&gt;
  addRegisterClass(MVT::v8i64, &amp;amp;NaplesPU::VR512LRegClass);&lt;br /&gt;
  addRegisterClass(MVT::v8f64, &amp;amp;NaplesPU::VR512LRegClass);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== setOperationAction ===&lt;br /&gt;
The '''setOperationAction''' method is used to tell the Code Generator the unsupported operation for the specified MachineValueType and the action to perform, this because by default every operation is considered '''Legal'''.&lt;br /&gt;
&lt;br /&gt;
This information is used by the LLVM Code Generator during the [http://llvm.org/docs/CodeGenerator.html#instruction-selection-section InstructionSelection] phase. So the input to give the function are the '''Operation Code''' (defined in the '''NodeType''' enum in &amp;quot;/compiler/include/llvm/CodeGen/ISDOpcodes.h&amp;quot;), the associated '''MachineValueTypes''' and the '''action''' to perform in order to legalize the operation. At this stage each operation is described by a Node in the SelectionDAG.&lt;br /&gt;
&lt;br /&gt;
The action must be one of those in the '''LegalizeAction''' enum contained in the '''TargetLoweringBase''' class (/compiler/include/llvm/Target/TargetLowering.h). Hence the possible actions are:&lt;br /&gt;
* '''Legal''', the target natively supports this operation.&lt;br /&gt;
* '''Promote''', this operation should be executed in a larger type.&lt;br /&gt;
* '''Expand''', try to expand this to other ops, otherwise use a libcall.&lt;br /&gt;
* '''LibCall''', don't try to expand this to other ops, always use a libcall.&lt;br /&gt;
* '''Custom''', use the '''LowerOperation''' hook to implement custom lowering.&lt;br /&gt;
&lt;br /&gt;
The most used in the NaplesPU+ backend are the ''Expand'' and the ''Custom'' actions.&lt;br /&gt;
As mentioned before, the '''Expand''' action tries to expand the node using equivalent operations, if this cannot be done, a function call is generated. The signature is defined in the '''InitLibcallNames''' in &amp;quot;/compiler/lib/CodeGen/TargetLoweringBase.cpp&amp;quot;.&lt;br /&gt;
With the '''Custom''' action, the lowering must be manually done implementing a proper function.&lt;br /&gt;
&lt;br /&gt;
== Custom Lowering ==&lt;br /&gt;
&lt;br /&gt;
When an operation must be custom lowered (using setOperationAction with Custom action), LLVM calls the '''LowerOperation''' function passing it the Node to lower and the DAG. The lowering is handled in this way:&lt;br /&gt;
*The '''LowerOperation''' function is implemented with a switch on the Node Opcode, according to its value returns the SDValue of a specific function.&lt;br /&gt;
*The operand specific functions are named as ''LowerOPERAND_NAME'' and they must generate the Machine Nodes that correspond to the input Node (object of SDValue class).&lt;br /&gt;
&lt;br /&gt;
=== Selection DAG Node representation ===&lt;br /&gt;
LLVM uses mainly three classes to represent a SelectionDAG: '''SDNode''' and '''SDValue''' and '''SDUse'''. They are defined in &amp;quot;/compiler/include/llvm/CodeGen/SelectionDAGNodes.h&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''SDNode''' class is the representation of a ''node'' in the Selection DAG and stores information about the operation type and its operands (list of SDUse objects). &lt;br /&gt;
The '''SDValue''' represents the output value of a SDNode. However, a SDNode may return muiltiple valuesas the result of a computation. Thus the SDValue stores informations about the SDNode as well as which return value to use from that node.&lt;br /&gt;
The '''SDUse''' class represents a a use of a SDNode and holds an SDValue, which records the SDNode being used and the result number, a pointer to the SDNode using the value, and Next and Prev pointers, which link together all the uses of an SDNode.&lt;br /&gt;
&lt;br /&gt;
From a visual point of view, we can imagine a Selection DAG as composed by nodes and and edges. &lt;br /&gt;
A node has an operand list, an operation, an ID (all of them stored in a SDNode object) and one or more output values (each one represented by a SDValue object). &lt;br /&gt;
An arrow goes from an input operand to a return value (informations stored in a a SDUse object) and represents data flow among nodes. There are also &amp;quot;chain&amp;quot; edges that represent control flow and provide an ordering between nodes that have side effects such as loads, stores, calls, returns, etc.&lt;br /&gt;
&lt;br /&gt;
It is possible to visualize, during a compilation, the DAGs LLVM generates by passing the flag &amp;quot;-mllvm -debug=isel&amp;quot; (textual form) or using the &amp;quot;-view*&amp;quot; options (visual form). Note that LLVM must be compiled in &amp;quot;Debug&amp;quot; mode in order to show such informations.&lt;br /&gt;
&lt;br /&gt;
=== Lowering ===&lt;br /&gt;
The purpose of a custom lowering node function is to substitute the input node with a '''legal''' node or DAG that performs the same operation. The difference among a &amp;quot;legal&amp;quot; DAG and an &amp;quot;illegal&amp;quot; one, is that the legal DAG uses only operations an types supported by the machine. &lt;br /&gt;
&lt;br /&gt;
For example lets analyze &amp;quot;LowerFNEG&amp;quot; function. It is used to lower the FNEG node using legal nodes. &lt;br /&gt;
The FNEG operation must perform the negation of a floating-point value (see &amp;quot;/compiler/include/llvm/CodeGen/ISDOpcodes.h&amp;quot; for definition). Since the NaplesPU architecture does not have an instruction to directly perform the operation, we have to perform the lowering manually.&lt;br /&gt;
&lt;br /&gt;
The first step is to declare in the NaplesPUTargetLowering class constructor that the FNEG operation must be custom lowered for all the supported floating-point types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
  // Note that this is just an example code. In NaplesPU backed &lt;br /&gt;
  // we use for loops to make the file more readable.&lt;br /&gt;
  setOperationAction(ISD::FNEG, MVT::f32, Custom);&lt;br /&gt;
  setOperationAction(ISD::FNEG, MVT::f64, Custom);&lt;br /&gt;
  setOperationAction(ISD::FNEG, MVT::v16f32, Custom);&lt;br /&gt;
  setOperationAction(ISD::FNEG, MVT::v8f64, Custom);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we update the switch in the &amp;quot;LowerOperation&amp;quot; function so that calls the &amp;quot;LowerFNEG&amp;quot; function, previously defined in the NaplesPUTargetLowering&amp;quot; interface (located in &amp;quot;/compiler/lib/Target/NaplesPU/NaplesPUISelLowering.h&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
 SDValue NaplesPUTargetLowering::LowerOperation(SDValue Op,&lt;br /&gt;
                                            SelectionDAG &amp;amp;DAG) const {&lt;br /&gt;
  ...&lt;br /&gt;
  case ISD::FNEG:&lt;br /&gt;
    return LowerFNEG(Op, DAG);&lt;br /&gt;
  ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
 class NaplesPUTargetLowering : public TargetLowering {&lt;br /&gt;
  public:&lt;br /&gt;
   ...&lt;br /&gt;
   SDValue LowerFNEG(SDValue Op, SelectionDAG &amp;amp;DAG) const;&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then we define the &amp;quot;LowerFNEG&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
SDValue NaplesPUTargetLowering::LowerFNEG(SDValue Op, SelectionDAG &amp;amp;DAG) const {&lt;br /&gt;
  SDLoc DL(Op);&lt;br /&gt;
  MVT ResultVT = Op.getValueType().getSimpleVT();&lt;br /&gt;
  MVT IntermediateVT;&lt;br /&gt;
&lt;br /&gt;
  if (ResultVT.isVector()) {&lt;br /&gt;
    IntermediateVT = &lt;br /&gt;
            (ResultVT.getVectorElementType() == MVT::f32) ? MVT::v16i32 : MVT::v8i64;&lt;br /&gt;
  } else {&lt;br /&gt;
    IntermediateVT = &lt;br /&gt;
            (ResultVT.getScalarType() == MVT::f32) ? MVT::i32 : MVT::i64;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  SDValue rhs = (IntermediateVT.getScalarType() == MVT::i32)   ? &lt;br /&gt;
                DAG.getConstant(0x80000000, DL, MVT::i32) :&lt;br /&gt;
                DAG.getConstant(0x8000000000000000, DL, MVT::i64);&lt;br /&gt;
                &lt;br /&gt;
  SDValue iconv;&lt;br /&gt;
  if (ResultVT.isVector())&lt;br /&gt;
    rhs = DAG.getNode(NaplesPUISD::SPLAT, DL, IntermediateVT, rhs);&lt;br /&gt;
&lt;br /&gt;
  iconv = DAG.getNode(ISD::BITCAST, DL, IntermediateVT, Op.getOperand(0));&lt;br /&gt;
  SDValue flipped = DAG.getNode(ISD::XOR, DL, IntermediateVT, iconv, rhs);&lt;br /&gt;
  return DAG.getNode(ISD::BITCAST, DL, ResultVT, flipped);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The two inputs are &amp;quot;SDValue Op&amp;quot; and &amp;quot;SelectionDAG &amp;amp;DAG&amp;quot;. '''Op''' is the node that must be lowered, in this case an FNEG operation. It is a SDValue object because in this way we have also information about the output value. '''DAG''' is used to create the nodes containing the operations the one contained in '''Op'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:FNEGScalar.png|frame|This image shows how  the FNEG is lowered in case of scalar floating-point value.]]&lt;br /&gt;
[[File:FNEGVector.png|frame|This image shows how  the FNEG is lowered in case of vector floating-point value. Differently from the scalar case, the SPLAT node is added before the XOR.]]&lt;br /&gt;
&lt;br /&gt;
The function must return the last of the legal nodes generated. The figures belove show lowering of FNEG node.&lt;br /&gt;
&lt;br /&gt;
According to the IEEE 754 standard the MSB is the sign bit, thus to negate a floating-point value the MSB must be inverted. This could be done by XORing the floating-point value with 0x80000000 (for 32-bit floating-point) or 0x8000000000000000 (for 64-bit floating-point).&lt;br /&gt;
The XOR operation, however, can only be done between integer operations. Thus floating-point operand must be bitcasted into an integer before XORing it. The bitcast operation tells LLVM to interpret a value with a different type with same width (e.g. i32 &amp;lt;-&amp;gt; f32). The inverse bistacst operation need to be done also for the XOR return value that must be interpreted as a floating-point.&lt;br /&gt;
&lt;br /&gt;
In case of the FNEG is done on a vector type, we must add another node to correctly load the constant 0x80000000 (or 0x8000000000000000). This is done through the SPLAT operation. This operation takes a scalar and copies it on all the vector elements. In hardware it corresponds to a move operation.&lt;br /&gt;
&lt;br /&gt;
The function code first checks the result type, in order to determine the appropriate integer type for the constant and XOR operation (It is stored in the &amp;quot;IntermediateVT&amp;quot; variable).&lt;br /&gt;
Then we use the &amp;quot;getConstant&amp;quot; method to generate the Constant Node. The method takes the constant value, a SDLoc object containing the '''Op''' IR location info and the value type.&lt;br /&gt;
&lt;br /&gt;
If the input operand type is a vector, we generate a SPLAT node. &lt;br /&gt;
Then we create the XOR node preceded and succeeded by the SPLAT operations.&lt;br /&gt;
&lt;br /&gt;
The method &amp;quot;getNode&amp;quot; is used to generate nodes. It takes the node Opcode, the SDLoc object, the output value type and the input operands. The function returns only the SDValue of the last BITCAST operation since it stores the informations about the previous nodes.&lt;br /&gt;
&lt;br /&gt;
The SPLAT node does not belong to the &amp;quot;ISD&amp;quot; namespace but to the &amp;quot;NaplesPUISD&amp;quot; namespace. This because LLVM does not have this node type and is defined only in the NaplesPU back-end. It will be resolved later during the Select phase using one of the patterns defined in [[NaplesPUInstrInfo.td]].&lt;br /&gt;
&lt;br /&gt;
The other lowering functions act in a similar way. They lower the input node using the SelectionDAG class methods according to the operation to implement and the input node informations. &lt;br /&gt;
However, there are cases in which nodes tagged to be custom lowered are simply expanded. This is done, for example, in the &amp;quot;LowerBUILD_VECTOR&amp;quot; function in which the BUILD_VECTOR node must be lowered with a SPLAT operation only if the vector it tries to build is composed by the same scalar value, otherwise the expansion of the BUILD_VECTOR node is sufficient. &lt;br /&gt;
&lt;br /&gt;
The way to tell the Code Generator that the node must be expanded is to return an empty SDValue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
SDValue NaplesPUTargetLowering::LowerBUILD_VECTOR(SDValue Op,&lt;br /&gt;
                                               SelectionDAG &amp;amp;DAG) const {&lt;br /&gt;
 // MVT VT = Op.getValueType().getSimpleVT();&lt;br /&gt;
  SDLoc DL(Op);&lt;br /&gt;
&lt;br /&gt;
  if (isSplatVector(Op.getNode())) {&lt;br /&gt;
    // This is a constant node that is duplicated to all lanes.&lt;br /&gt;
    // Convert it to a SPLAT node.&lt;br /&gt;
    return CheckSplat(Op, Op.getOperand(0), DAG);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return SDValue(); // Expand&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Custom MachineInstruction Insertion ==&lt;br /&gt;
&lt;br /&gt;
Another way to lower unsupported operations is to manually emit Machine Instructions. The emission of Machine Instructions takes place just before the '''Register Allocation'''. It is important to remember that the Machine Instructions are still in SSA form, so care must be taken when creating virtual registers.&lt;br /&gt;
&lt;br /&gt;
To instruct LLVM about what operations must have a custom inserter, a (pseudo)instruction in [[NaplesPUInstrInfo.td]] with the '''usesCustomInserter''' flag setted to 1 must be defined.&lt;br /&gt;
&lt;br /&gt;
When an MachineInstruction must be custom inserted, LLVM calls the '''EmitInstrWithCustomInserter''' function passing it the Machine Instruction to lower and the Basic Block, the instruction belongs:&lt;br /&gt;
*The '''EmitInstrWithCustomInserter''' function is implemented with a switch on the Machine Instruction Opcode, according to its value returns the modified input basic block.&lt;br /&gt;
*The operand specific functions are named as ''EmitOPERATION_NAME'' and they must generate the instructions that correspond to the input Machine Instruction.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Insertion ===&lt;br /&gt;
The purpose of a custom instruction inserter function is to substitute the input Machine Instruction with instructions that perform the same operation.&lt;br /&gt;
&lt;br /&gt;
For example, lets consider the &amp;quot;EmitLoadI32&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
In NaplesPU, the immediate field of type I instruction is 16 bits wide so to load a 32-bit immediate value the instruction couple MOVEIH-MOVEIL must be emitted.&lt;br /&gt;
&lt;br /&gt;
The EmitLoadI32 function is called by the EmitInstrWithCustomInserter hook function. The latter is called when the Code Generator encounters a machine instruction which has the usesCustomInserter flag setted to 1.&lt;br /&gt;
&lt;br /&gt;
Therefore, in NaplesPUInstrInfo.td, the pseudo-instruction '''LoadI32''' is defined with usesCustomInserter = 1. The corresponding node is generated during the Select phase, when the pattern &amp;quot;(set i32:$dst, (i32 imm:$val))&amp;quot; is detected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def LoadI32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$val),&lt;br /&gt;
    [(set i32:$dst, (i32 imm:$val))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When must emit the instruction corresponding to '''LoadI32''', the &amp;quot;EmitLoadI32&amp;quot; is called (through the EmitInstrWithCustomInserter hook function). &lt;br /&gt;
The emit functions have at least two inputs ([http://llvm.org/docs/CodeGenerator.html#the-machineinstr-class MachineInstr] *MI and [http://llvm.org/docs/CodeGenerator.html#the-machinebasicblock-class MachineBasicBlock] *BB) and must return the MachineBasicBlock modified.&lt;br /&gt;
&lt;br /&gt;
To emit instructions the '''BuildMI''' interface (defined in &amp;quot;/compiler/include/llvm/CodeGen/MachineInstrBuilder.h&amp;quot;) is used. This interface allows a simple way to generate instructions, providing methods like addReg, addImm and etc.&lt;br /&gt;
&lt;br /&gt;
In the case of the EmitLoadI32, first the immediate values is taken from the LoadI32 operation, then the InsertLoad32Immediate function is called. This function is responsible of generating the MOVEIH-MOVEIL instruction couple. At last LoadI32 is deleted and the resulting Basic Block is returned.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
MachineBasicBlock *&lt;br /&gt;
NaplesPUTargetLowering::EmitLoadI32(MachineInstr *MI,&lt;br /&gt;
                                  MachineBasicBlock *BB) const {&lt;br /&gt;
&lt;br /&gt;
  DebugLoc DL = MI-&amp;gt;getDebugLoc();&lt;br /&gt;
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();&lt;br /&gt;
  &lt;br /&gt;
  // Get the integer immediate value.&lt;br /&gt;
  int64_t ImmOp = MI-&amp;gt;getOperand(1).getImm();&lt;br /&gt;
  // Call the fuction that generates the MIs.&lt;br /&gt;
  InsertLoad32Immediate(MI, BB, TII, &amp;amp;DL, MI-&amp;gt;getOperand(0).getReg(), ImmOp);&lt;br /&gt;
&lt;br /&gt;
  MI-&amp;gt;eraseFromParent();&lt;br /&gt;
&lt;br /&gt;
  return BB;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The InsertLoad32Immediate function uses the BuildMI interface to generate the instructions. There are several versions of BuildMI, the one used takes as inputs the MachineBasicBlock where to insert the instructions, the pointer to the MachineInstruction before which insert the new instruction, a DebugLoc and the instruction description (MCInstrDesc class object) it must generate.&lt;br /&gt;
The instruction description is obtained through the TargetInstrInfo get method passing it the instruction name. &lt;br /&gt;
&lt;br /&gt;
Note: in a Machine Instruction the first operand is the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
void InsertLoad32Immediate (MachineInstr *MI, MachineBasicBlock *BB,&lt;br /&gt;
                            const TargetInstrInfo *TII, DebugLoc *DL,&lt;br /&gt;
                            unsigned DestReg, int64_t Immediate) {&lt;br /&gt;
&lt;br /&gt;
  BuildMI(*BB, *MI, *DL, TII-&amp;gt;get(NaplesPU::MOVEIHSI))&lt;br /&gt;
              .addReg(DestReg, RegState::Define)&lt;br /&gt;
              .addImm(((Immediate &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF));&lt;br /&gt;
  BuildMI(*BB, *MI, *DL, TII-&amp;gt;get(NaplesPU::MOVEILSI))&lt;br /&gt;
              .addReg(DestReg)&lt;br /&gt;
              .addImm((Immediate &amp;amp; 0xFFFF));&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the instruction are still in SSA form, the code above shows a workaround to use the same destination register. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Methods ==&lt;br /&gt;
&lt;br /&gt;
The NaplesPUTargetLowering class redefines also some other methods used to instruct the Code Generator about the specific capabilities supported or unsupported by the NaplesPU architecture.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUInstrInfo.td&amp;diff=2135</id>
		<title>NaplesPUInstrInfo.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUInstrInfo.td&amp;diff=2135"/>
				<updated>2019-06-21T15:02:34Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
NaplesPUInstrInfo.td and [[NaplesPUInstrFormats.td]] describe the NaplesPU instructions and the patterns to transform LLVM IR into machine code. The NaplesPUInstrInfo.td contains the instructions definition and the patterns necessary for the translation from the LLVM IR to the NaplesPU machine code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NaplesPUInstrInfo.td - Target Description for NaplesPU Target -----------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This file describes the NaplesPU instructions in TableGen format.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Instruction format superclass&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
include &amp;quot;NaplesPUInstrFormats.td&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Instruction definition&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Arithmetic Instructions (Format R &amp;amp; I)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//Arithmetic Integer Two operands&lt;br /&gt;
defm OR     : FArithInt_TwoOp&amp;lt;&amp;quot;or&amp;quot;, or, 1&amp;gt;;&lt;br /&gt;
defm AND    : FArithInt_TwoOp&amp;lt;&amp;quot;and&amp;quot;, and, 2&amp;gt;;&lt;br /&gt;
defm XOR    : FArithInt_TwoOp&amp;lt;&amp;quot;xor&amp;quot;, xor, 3&amp;gt;;&lt;br /&gt;
defm ADD    : FArithInt_TwoOp&amp;lt;&amp;quot;add&amp;quot;, add, 4&amp;gt;;&lt;br /&gt;
defm SUB    : FArithInt_TwoOp&amp;lt;&amp;quot;sub&amp;quot;, sub, 5&amp;gt;;&lt;br /&gt;
defm MULL   : FArithInt_TwoOp&amp;lt;&amp;quot;mull&amp;quot;, mul, 6&amp;gt;;&lt;br /&gt;
defm MULH   : FArithInt_TwoOp&amp;lt;&amp;quot;mulhs&amp;quot;, mulhs, 7&amp;gt;;&lt;br /&gt;
defm MULHU  : FArithInt_TwoOp&amp;lt;&amp;quot;mulhu&amp;quot;, mulhu, 8&amp;gt;;&lt;br /&gt;
defm SRA    : FSRInt_TwoOp&amp;lt;&amp;quot;ashr&amp;quot;, sra, 9&amp;gt;;&lt;br /&gt;
defm SRL    : FSRInt_TwoOp&amp;lt;&amp;quot;shr&amp;quot;, srl, 10&amp;gt;;&lt;br /&gt;
defm SLL    : FSRInt_TwoOp&amp;lt;&amp;quot;shl&amp;quot;, shl, 11&amp;gt;;&lt;br /&gt;
//Arithmetic Integer One operand&lt;br /&gt;
defm CLZ    : FArithInt_OneOp&amp;lt;&amp;quot;clz&amp;quot;, ctlz, 12&amp;gt;;&lt;br /&gt;
defm CTZ    : FArithInt_OneOp&amp;lt;&amp;quot;ctz&amp;quot;, cttz, 13&amp;gt;;&lt;br /&gt;
//Compare Integer&lt;br /&gt;
defm SEQSI : FCompInt&amp;lt;&amp;quot;cmpeq&amp;quot;, SETEQ, 14, int_npu_mask_cmpi32_eq&amp;gt;;//, int_npu_mask_cmpi64_eq&amp;gt;;&lt;br /&gt;
defm SNESI : FCompInt&amp;lt;&amp;quot;cmpne&amp;quot;, SETNE, 15, int_npu_mask_cmpi32_ne&amp;gt;;//, int_npu_mask_cmpi64_ne&amp;gt;;&lt;br /&gt;
defm SGTSI : FCompInt&amp;lt;&amp;quot;cmpgt&amp;quot;, SETGT, 16, int_npu_mask_cmpi32_sgt&amp;gt;;//, int_npu_mask_cmpi64_sgt&amp;gt;;&lt;br /&gt;
defm SGESI : FCompInt&amp;lt;&amp;quot;cmpge&amp;quot;, SETGE, 17, int_npu_mask_cmpi32_sge&amp;gt;;//, int_npu_mask_cmpi64_sge&amp;gt;;&lt;br /&gt;
defm SLTSI : FCompInt&amp;lt;&amp;quot;cmplt&amp;quot;, SETLT, 18, int_npu_mask_cmpi32_slt&amp;gt;;//, int_npu_mask_cmpi64_slt&amp;gt;;&lt;br /&gt;
defm SLESI : FCompInt&amp;lt;&amp;quot;cmple&amp;quot;, SETLE, 19, int_npu_mask_cmpi32_sle&amp;gt;;//, int_npu_mask_cmpi64_sle&amp;gt;;&lt;br /&gt;
//Compare Unsigned&lt;br /&gt;
defm SGTUI : FCompInt&amp;lt;&amp;quot;cmpugt&amp;quot;, SETUGT, 20, int_npu_mask_cmpi32_ugt&amp;gt;;//, int_npu_mask_cmpi64_ugt&amp;gt;;&lt;br /&gt;
defm SGEUI : FCompInt&amp;lt;&amp;quot;cmpuge&amp;quot;, SETUGE, 21, int_npu_mask_cmpi32_uge&amp;gt;;//, int_npu_mask_cmpi64_uge&amp;gt;;&lt;br /&gt;
defm SLTUI : FCompInt&amp;lt;&amp;quot;cmpult&amp;quot;, SETULT, 22, int_npu_mask_cmpi32_ult&amp;gt;;//, int_npu_mask_cmpi64_ult&amp;gt;;&lt;br /&gt;
defm SLEUI : FCompInt&amp;lt;&amp;quot;cmpule&amp;quot;, SETULE, 23, int_npu_mask_cmpi32_ule&amp;gt;;//, int_npu_mask_cmpi64_ule&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Cross Product Instruction&lt;br /&gt;
def CROSSPROD_32 : FR_TwoOp_Unmasked_32 &amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
  &amp;quot;crp $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
  [(set v16i32:$dst, (int_npu_crossprodv16i32 v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
  63,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Shuffle&lt;br /&gt;
def SHUFFLEI_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
  &amp;quot;shuffle_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
  [(set v16i32:$dst, (int_npu_shufflei32 v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
  24,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Get lane&lt;br /&gt;
def GET_LANEI_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
  &amp;quot;getlane_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, (extractelt v16i32:$src0, i32:$src1))],&lt;br /&gt;
  25,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def GET_LANEIimm : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins VR512W:$src, SIMM9OP:$imm),&lt;br /&gt;
  &amp;quot;getlanei $dst, $src, $imm&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, (extractelt v16i32:$src, simm9:$imm))],&lt;br /&gt;
  25,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Move register - register&lt;br /&gt;
def MOVE_SS_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [],&lt;br /&gt;
  32,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def MOVE_VS_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set v16i32:$dst, (splat i32:$src0))],&lt;br /&gt;
  32,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def MOVE_VV_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0),&lt;br /&gt;
  &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [],&lt;br /&gt;
  32,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
let Constraints = &amp;quot;$dst = $oldvalue&amp;quot;, isAsmParserOnly=1 in {&lt;br /&gt;
&lt;br /&gt;
  def MOVE_VS_M_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins GPR32:$src0, VR512W:$oldvalue),&lt;br /&gt;
    &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_npu_vector_mixi32 (splat i32:$src0), v16i32:$oldvalue))],&lt;br /&gt;
    32,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def MOVE_VV_M_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
    &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_npu_vector_mixi32 v16i32:$src0, v16i32:$oldvalue))],&lt;br /&gt;
    32,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Arithmetic Float Two operands&lt;br /&gt;
defm ADDF   : FArithFloat_TwoOp&amp;lt;&amp;quot;fadd&amp;quot;, fadd, 33&amp;gt;;&lt;br /&gt;
defm SUBF   : FArithFloat_TwoOp&amp;lt;&amp;quot;fsub&amp;quot;, fsub, 34&amp;gt;;&lt;br /&gt;
defm MULF   : FArithFloat_TwoOp&amp;lt;&amp;quot;fmul&amp;quot;, fmul, 35&amp;gt;;&lt;br /&gt;
defm DIVF   : FArithFloat_TwoOp&amp;lt;&amp;quot;fdiv&amp;quot;, fdiv, 36&amp;gt;;&lt;br /&gt;
//Compare Float&lt;br /&gt;
def FloatCompareType: SDTypeProfile&amp;lt;1, 2, [&lt;br /&gt;
  SDTCisInt&amp;lt;0&amp;gt;, SDTCisFP&amp;lt;1&amp;gt;, SDTCisSameAs&amp;lt;1, 2&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
def FGT: SDNode&amp;lt;&amp;quot;NaplesPUISD::FGT&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FGE: SDNode&amp;lt;&amp;quot;NaplesPUISD::FGE&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FLT: SDNode&amp;lt;&amp;quot;NaplesPUISD::FLT&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FLE: SDNode&amp;lt;&amp;quot;NaplesPUISD::FLE&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FEQ: SDNode&amp;lt;&amp;quot;NaplesPUISD::FEQ&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FNE: SDNode&amp;lt;&amp;quot;NaplesPUISD::FNE&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
defm SEQFO : FCompFloat&amp;lt;&amp;quot;cmpfeq&amp;quot;, FEQ, 37, int_npu_mask_cmpf32_eq&amp;gt;;//, int_npu_mask_cmpf64_eq&amp;gt;;&lt;br /&gt;
defm SNEFO : FCompFloat&amp;lt;&amp;quot;cmpfne&amp;quot;, FNE, 38, int_npu_mask_cmpf32_ne&amp;gt;;//, int_npu_mask_cmpf64_ne&amp;gt;;&lt;br /&gt;
defm SGTFO : FCompFloat&amp;lt;&amp;quot;cmpfgt&amp;quot;, FGT, 39, int_npu_mask_cmpf32_gt&amp;gt;;//, int_npu_mask_cmpf64_gt&amp;gt;;&lt;br /&gt;
defm SGEFO : FCompFloat&amp;lt;&amp;quot;cmpfge&amp;quot;, FGE, 40, int_npu_mask_cmpf32_ge&amp;gt;;//, int_npu_mask_cmpf64_ge&amp;gt;;&lt;br /&gt;
defm SLTFO : FCompFloat&amp;lt;&amp;quot;cmpflt&amp;quot;, FLT, 41, int_npu_mask_cmpf32_lt&amp;gt;;//, int_npu_mask_cmpf64_lt&amp;gt;;&lt;br /&gt;
defm SLEFO : FCompFloat&amp;lt;&amp;quot;cmpfle&amp;quot;, FLE, 42, int_npu_mask_cmpf32_le&amp;gt;;//, int_npu_mask_cmpf64_le&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//sign extension&lt;br /&gt;
defm SEXT8_32 : FSext_32&amp;lt;&amp;quot;sext8&amp;quot;, i8, 43, v16i8&amp;gt;;&lt;br /&gt;
defm SEXT16_32 : FSext_32&amp;lt;&amp;quot;sext16&amp;quot;, i16, 44, v16i16&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Integer to Float conversion&lt;br /&gt;
def I32TOF32_SS : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;itof_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set f32:$dst, (sint_to_fp i32:$src0))],&lt;br /&gt;
  48,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def I32TOF32_VV_U : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0),&lt;br /&gt;
  &amp;quot;itof_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set v16f32:$dst, (sint_to_fp v16i32:$src0))],&lt;br /&gt;
  48,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
  def I32TOF32_VV_M : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
    &amp;quot;itof_i32.m $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (int_npu_vector_mixf32 (sint_to_fp v16i32:$src0), v16f32:$oldvalue))],&lt;br /&gt;
    48,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Float to Integer conversion&lt;br /&gt;
def F32TOI32_SS : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;ftoi_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, (fp_to_sint f32:$src0))],&lt;br /&gt;
  49,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def F32TOI32_VV_U : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0),&lt;br /&gt;
  &amp;quot;ftoi_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set v16i32:$dst, (fp_to_sint v16f32:$src0))],&lt;br /&gt;
  49,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
  def F32TOI32_VV_M : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
    &amp;quot;ftoi_i32.m $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_npu_vector_mixi32 (fp_to_sint v16f32:$src0), v16i32:$oldvalue))],&lt;br /&gt;
    49,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// MOVEI Instructions (Format MOVEI)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
defm MOVEIL : FMOVEI_ALL&amp;lt;&amp;quot;moveil&amp;quot;, 0&amp;gt;;&lt;br /&gt;
defm MOVEIH : FMOVEI_ALL&amp;lt;&amp;quot;moveih&amp;quot;, 1&amp;gt;;&lt;br /&gt;
defm MOVEI : FMOVEI_ALL&amp;lt;&amp;quot;movei&amp;quot;, 2&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// LOAD/STORE SPECIAL REGISTERS&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def READMR  : READ_SPR&amp;lt;MaskReg, &amp;quot;read_mr&amp;quot;, int_npu_read_mask_reg&amp;gt;;&lt;br /&gt;
def WRITEMR : WRITE_SPR&amp;lt;MaskReg, &amp;quot;write_mr&amp;quot;, int_npu_write_mask_reg&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Create Mask Instruction&lt;br /&gt;
def CREATEMASK_32 : FR_OneOp_Unmasked_32 &amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins VR512W:$src0),&lt;br /&gt;
  &amp;quot;crt_mask_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, (int_npu_createmaskv16i32 v16i32:$src0))],&lt;br /&gt;
  50,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// MEM Instructions (Format M)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// Scalar load to 32-bit registers&lt;br /&gt;
defm L32BS : FMLoadScalar_32&amp;lt;&amp;quot;_s8&amp;quot;, sextloadi8_mem, sextloadi8_scratch, 0&amp;gt;;&lt;br /&gt;
defm L32SS : FMLoadScalar_32&amp;lt;&amp;quot;_s16&amp;quot;, sextloadi16_mem, sextloadi16_scratch, 1&amp;gt;;&lt;br /&gt;
defm L32W  : FMLoadScalar_32&amp;lt;&amp;quot;&amp;quot;, MemLoad, ScratchpadLoad, 2&amp;gt;;&lt;br /&gt;
defm L32BU : FMLoadScalar_32&amp;lt;&amp;quot;_u8&amp;quot;, zextloadi8_mem, zextloadi8_scratch, 4&amp;gt;;&lt;br /&gt;
defm L32SU : FMLoadScalar_32&amp;lt;&amp;quot;_u16&amp;quot;, zextloadi16_mem, zextloadi16_scratch, 5&amp;gt;;&lt;br /&gt;
defm S32B : FMStoreScalar_32&amp;lt;&amp;quot;_8&amp;quot;, truncstorei8_mem, truncstorei8_scratch, 32&amp;gt;;&lt;br /&gt;
defm S32S : FMStoreScalar_32&amp;lt;&amp;quot;_16&amp;quot;, truncstorei16_mem, truncstorei16_scratch, 33&amp;gt;;&lt;br /&gt;
defm S32W : FMStoreScalar_32&amp;lt;&amp;quot;&amp;quot;, MemStore, ScratchpadStore, 34&amp;gt;;&lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
//Vector load block &lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
&lt;br /&gt;
// Vector load to 32-bit registers&lt;br /&gt;
defm LV32B : FMLoadVector_32&amp;lt;&amp;quot;_v16i8&amp;quot;, sextloadv16i8_mem, sextloadv16i8_scratch, &lt;br /&gt;
                              int_npu_block_loadv16i8_masked, int_npu_block_loadv16i8_scratchpad_masked, &lt;br /&gt;
                              7&amp;gt;;&lt;br /&gt;
defm LV32S : FMLoadVector_32&amp;lt;&amp;quot;_v16i16&amp;quot;, sextloadv16i16_mem, sextloadv16i16_scratch, &lt;br /&gt;
                              int_npu_block_loadv16i16_masked, int_npu_block_loadv16i16_scratchpad_masked, &lt;br /&gt;
                              8&amp;gt;;&lt;br /&gt;
defm LV32W : FMLoadVector_32&amp;lt;&amp;quot;_v16i32&amp;quot;, MemLoad, ScratchpadLoad, &lt;br /&gt;
                              int_npu_block_loadv16i32_masked, int_npu_block_loadv16i32_scratchpad_masked, &lt;br /&gt;
                              9&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
defm LV32BU : FMLoadVector_32&amp;lt;&amp;quot;_v16u8&amp;quot;, zextloadv16i8_mem, zextloadv16i8_scratch, &lt;br /&gt;
                              int_npu_block_loadv16u8_masked, int_npu_block_loadv16u8_scratchpad_masked, &lt;br /&gt;
                              11&amp;gt;;&lt;br /&gt;
defm LV32SU : FMLoadVector_32&amp;lt;&amp;quot;_v16u16&amp;quot;, zextloadv16i16_mem, zextloadv16i16_scratch, &lt;br /&gt;
                              int_npu_block_loadv16u16_masked, int_npu_block_loadv16u16_scratchpad_masked, &lt;br /&gt;
                              12&amp;gt;;&lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
//Vector load gather &lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
&lt;br /&gt;
// Vector gather to 32-bit registers&lt;br /&gt;
defm GLV32W : FMGather_32&amp;lt;&amp;quot;32&amp;quot;, int_npu_gather_loadi32_scratchpad,&lt;br /&gt;
                          int_npu_gather_loadi32_scratchpad_masked,&lt;br /&gt;
                          16&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
//Vector store block &lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
&lt;br /&gt;
// Vector store from 32-bit registers&lt;br /&gt;
defm SV32B : FMStoreVector_32&amp;lt;&amp;quot;_v16i8&amp;quot;, truncstorev16i8_mem, truncstorev16i8_scratch, &lt;br /&gt;
                              int_npu_block_storev16i8_masked, int_npu_block_storev16i8_scratchpad_masked, &lt;br /&gt;
                              36&amp;gt;;&lt;br /&gt;
defm SV32S : FMStoreVector_32&amp;lt;&amp;quot;_v16i16&amp;quot;, truncstorev16i16_mem, truncstorev16i16_scratch, &lt;br /&gt;
                              int_npu_block_storev16i16_masked, int_npu_block_storev16i16_scratchpad_masked, &lt;br /&gt;
                              37&amp;gt;;&lt;br /&gt;
defm SV32W : FMStoreVector_32&amp;lt;&amp;quot;_v16i32&amp;quot;, MemStore, ScratchpadStore, &lt;br /&gt;
                              int_npu_block_storev16i32_masked, int_npu_block_storev16i32_scratchpad_masked, &lt;br /&gt;
                              38&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
//Vector store scatter &lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
&lt;br /&gt;
// Vector scatter from 32-bit registers&lt;br /&gt;
defm SSV32W : FMScatter_32&amp;lt;&amp;quot;32&amp;quot;,int_npu_scatter_storei32_scratchpad, &lt;br /&gt;
                              int_npu_scatter_storei32_scratchpad_masked, &lt;br /&gt;
                              42&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Jump and Branch Instructions (Format J/JR)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
let isTerminator = 1 in {&lt;br /&gt;
  //Unconditional jump with offset, PC:=PC+addr&lt;br /&gt;
  def JMP : FJ&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins brtarget:$addr),&lt;br /&gt;
    &amp;quot;jmp $addr&amp;quot;,&lt;br /&gt;
    [(br bb:$addr)],&lt;br /&gt;
    0&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    let isBarrier = 1;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  //Unconditional jump with register PC:=DST&lt;br /&gt;
  def JUMPREG : FJR&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins GPR32:$cond),&lt;br /&gt;
  &amp;quot;jmp $cond&amp;quot;,&lt;br /&gt;
  [(brind i32:$cond)],&lt;br /&gt;
  0&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    let isBranch = 1;&lt;br /&gt;
    let isIndirectBranch = 1;&lt;br /&gt;
    let isBarrier = 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Return PC:=RA&lt;br /&gt;
  def JRET : FJR&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins),&lt;br /&gt;
  &amp;quot;jret&amp;quot;,&lt;br /&gt;
  [(return)],&lt;br /&gt;
  3&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    let Inst{23-18} = 0;&lt;br /&gt;
    let Inst{17-0} = 0;&lt;br /&gt;
&lt;br /&gt;
    let isReturn = 1;&lt;br /&gt;
    let isTerminator = 1;&lt;br /&gt;
    let isBarrier = 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //Conditional Branch&lt;br /&gt;
  def BEQZ : FJR&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$cond, brtarget:$addr),&lt;br /&gt;
    &amp;quot;beqz $cond, $addr&amp;quot;,&lt;br /&gt;
    [],&lt;br /&gt;
    5&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  //Conditional Branch&lt;br /&gt;
  def BNEZ : FJR&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$cond, brtarget:$addr),&lt;br /&gt;
    &amp;quot;bnez $cond, $addr&amp;quot;,&lt;br /&gt;
    [],&lt;br /&gt;
    6&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
let isCall = 1, Defs = [ RA_REG ] in {&lt;br /&gt;
  //Jump with offset and save return address RA:=PC+4, PC:=PC+addr&lt;br /&gt;
  def JMPSR_OFF : FJ&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins calltarget:$addr, variable_ops),&lt;br /&gt;
    &amp;quot;jmpsr $addr&amp;quot;,&lt;br /&gt;
    [],&lt;br /&gt;
    1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  //Jump with register and save return address RA:=PC+4, PC:=DST&lt;br /&gt;
  def JMPSR_REG : FJR&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$dst, variable_ops),&lt;br /&gt;
    &amp;quot;jmpsr $dst&amp;quot;,&lt;br /&gt;
    [(call i32:$dst)],&lt;br /&gt;
    1&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
    let Inst{23-18} = dst;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Control Instructions (Format C)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def BARRIER : FC&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
  &amp;quot;barrier $src0, $src1&amp;quot;,&lt;br /&gt;
  [(int_npu_barrier i32:$src0, i32:$src1)],&lt;br /&gt;
  0&amp;gt;;&lt;br /&gt;
  &lt;br /&gt;
def FLUSH : FC&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;flush $src0&amp;quot;,&lt;br /&gt;
  [(int_npu_flush i32:$src0)],&lt;br /&gt;
  2&amp;gt;{&lt;br /&gt;
    let Inst{17-12} = 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
// READ Control Register&lt;br /&gt;
def READCR : FC&amp;lt;&lt;br /&gt;
  (outs GPR32:$src0),&lt;br /&gt;
  (ins GPR32:$src1),&lt;br /&gt;
  &amp;quot;read_cr $src0, $src1&amp;quot;,&lt;br /&gt;
  [(set i32:$src0, (int_npu_read_control_reg i32:$src1))],&lt;br /&gt;
  3&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// WRITE Control Register&lt;br /&gt;
def WRITECR : FC&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
  &amp;quot;write_cr $src0, $src1&amp;quot;,&lt;br /&gt;
  [(int_npu_write_control_reg i32:$src0, i32:$src1)],&lt;br /&gt;
  4&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Miscellaneous Instructions&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def NOP : InstNaplesPU&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins),&lt;br /&gt;
  &amp;quot;nop&amp;quot;,&lt;br /&gt;
  []&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  let Inst{31-0} = 0xffffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def LOAD_EFFECTIVE_ADDR : InstNaplesPU&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins LEAri:$addr),&lt;br /&gt;
  &amp;quot;_lea $dst, $addr&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, ADDRri:$addr)]&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  let isAsmParserOnly = 1;   // Don't disassemble&lt;br /&gt;
&lt;br /&gt;
  bits&amp;lt;16&amp;gt; addr;&lt;br /&gt;
  bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-29} = 0b010;&lt;br /&gt;
  let Inst{28-24} = 4;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-2} = addr;&lt;br /&gt;
  let Inst{1} = 0;&lt;br /&gt;
  let Inst{0} = 0;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//TODO: (Catello) Add symbol in NaplesPUAsmParser::ProcessInstruction.&lt;br /&gt;
// This node defines the lea pseudo-instruction that can be used in&lt;br /&gt;
// assembly files.&lt;br /&gt;
def LOAD_EFFECTIVE_ADDR_SYM : InstNaplesPU&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins symref:$label),&lt;br /&gt;
  &amp;quot;lea $dst, $label&amp;quot;,&lt;br /&gt;
  []&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  let isPseudo = 1;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def LEAH : InstNaplesPU&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins ABSh:$addr),&lt;br /&gt;
  &amp;quot;leah $dst, $addr&amp;quot;,&lt;br /&gt;
  []&amp;gt; {&lt;br /&gt;
  let isAsmParserOnly = 1;   // Don't disassemble&lt;br /&gt;
&lt;br /&gt;
  bits&amp;lt;16&amp;gt; addr;&lt;br /&gt;
  bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-27} = 0b01100; // Format MOVEI&lt;br /&gt;
  let Inst{26-24} = 1; //Opcode MOVEI&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-2} = addr;&lt;br /&gt;
  let Inst{1} = 0;&lt;br /&gt;
  let Inst{0} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def LEAL : InstNaplesPU&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$addrh, ABSl:$addr),&lt;br /&gt;
  &amp;quot;leal $dst, $addr&amp;quot;,&lt;br /&gt;
  []&amp;gt; {&lt;br /&gt;
  let isAsmParserOnly = 1;   // Don't disassemble&lt;br /&gt;
  &lt;br /&gt;
  //costraint used to let llvm use the same destination register as leah&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $addrh&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
  bits&amp;lt;16&amp;gt; addr;&lt;br /&gt;
  bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-27} = 0b01100; // Format MOVEI&lt;br /&gt;
  let Inst{26-24} = 0; //Opcode MOVEI&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-2} = addr;&lt;br /&gt;
  let Inst{1} = 0;&lt;br /&gt;
  let Inst{0} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Pseudo instructions&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// These pseudo ops capture outgoing argument space on the stack and will be removed&lt;br /&gt;
// by later passes.&lt;br /&gt;
let Defs = [ SP_REG ], Uses = [ SP_REG ], hasSideEffects = 1 in {&lt;br /&gt;
   def ADJCALLSTACKDOWN : Pseudo&amp;lt;&lt;br /&gt;
     (outs),&lt;br /&gt;
     (ins i32imm:$amt1, i32imm:$amt2),&lt;br /&gt;
     [(callseq_start timm:$amt1, timm:$amt2)]&amp;gt;;&lt;br /&gt;
 &lt;br /&gt;
   def ADJCALLSTACKUP : Pseudo&amp;lt;&lt;br /&gt;
     (outs),&lt;br /&gt;
     (ins i32imm:$amt1, i32imm:$amt2),&lt;br /&gt;
     [(callseq_end timm:$amt1, timm:$amt2)]&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// SELECT pseudo instructions. This architecture doesn't actually have a scalar&lt;br /&gt;
// conditional move instruction. These will be replaced in a later pass&lt;br /&gt;
// with a diamond pattern of conditional branches.&lt;br /&gt;
//&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def SELECTI : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$pred, GPR32:$true, GPR32:$false),&lt;br /&gt;
    [(set i32:$dst, (selcondresult i32:$pred, i32:$true, i32:$false))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def SELECTF : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$pred, GPR32:$true, GPR32:$false),&lt;br /&gt;
    [(set f32:$dst, (selcondresult i32:$pred, f32:$true, f32:$false))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def SELECTVI : Pseudo&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins GPR32:$pred, VR512W:$true, VR512W:$false),&lt;br /&gt;
    [(set v16i32:$dst, (selcondresult i32:$pred, v16i32:$true, v16i32:$false))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def SELECTVF : Pseudo&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins GPR32:$pred, VR512W:$true, VR512W:$false),&lt;br /&gt;
    [(set v16f32:$dst, (selcondresult i32:$pred, v16f32:$true, v16f32:$false))]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def LoadI32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$val),&lt;br /&gt;
    [(set i32:$dst, (i32 imm:$val))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def LoadF32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$val),&lt;br /&gt;
    [(set f32:$dst, (f32 fpimm:$val))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def InsertELT32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$vec, GPR32:$elem, GPR32:$pos),&lt;br /&gt;
    [(set v16i32:$dst, (insert_elt v16i32:$vec, i32:$elem, i32:$pos))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def : Pat &amp;lt;(v16f32 (insert_elt v16f32:$vec, f32:$elem, i32:$pos)), (v16f32 (InsertELT32 v16f32:$vec, f32:$elem, i32:$pos))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Atomics&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
 defm ATOMIC_LOAD_ADD : AtomicBinary&amp;lt;atomic_load_add&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_SUB : AtomicBinary&amp;lt;atomic_load_sub&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_AND : AtomicBinary&amp;lt;atomic_load_and&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_OR  : AtomicBinary&amp;lt;atomic_load_or&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_XOR : AtomicBinary&amp;lt;atomic_load_xor&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_NAND : AtomicBinary&amp;lt;atomic_load_nand&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def ATOMIC_CMP_SWAP : Pseudo&amp;lt;&lt;br /&gt;
   (outs GPR32:$dst),&lt;br /&gt;
   (ins GPR32:$ptr, GPR32:$cmp, GPR32:$swap),&lt;br /&gt;
   [(set i32:$dst, (atomic_cmp_swap GPR32:$ptr, GPR32:$cmp, GPR32:$swap))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
 def ATOMIC_SWAP : Pseudo&amp;lt;&lt;br /&gt;
   (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$ptr, GPR32:$swap),&lt;br /&gt;
   [(set i32:$dst, (atomic_swap GPR32:$ptr, GPR32:$swap))]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Non-Instruction Patterns&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// Shuffle patterns&lt;br /&gt;
def : Pat&amp;lt;(int_npu_shufflef32 v16f32:$src0, v16i32:$src1),&lt;br /&gt;
  (SHUFFLEI_32 v16f32:$src0, v16i32:$src1)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Splat patterns&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (splat i32:$src0)), (MOVE_VS_32 i32:$src0)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (splat f32:$src0)), (MOVE_VS_32 f32:$src0)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(int_npu_vector_mixf32 v16f32:$src0, v16f32:$oldvalue),&lt;br /&gt;
          (MOVE_VV_M_32 v16f32:$src0, v16f32:$oldvalue)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- Patterns for load and store ----------------//&lt;br /&gt;
//---------------- scalar load and store ----------------//&lt;br /&gt;
// zextload bool -&amp;gt; zextload byte&lt;br /&gt;
def : Pat&amp;lt;(i32 (zextloadi1_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (zextloadi1_scratch ADDRri:$addr)), (L32BU_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- scalar extload-&amp;gt;zextload ----------------//&lt;br /&gt;
// Scalar load to 32-bit registers &lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi1_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi8_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi16_mem ADDRri:$addr)), (L32SU_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(f32 (MemLoad ADDRri:$addr)), (L32W_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi1_scratch ADDRri:$addr)), (L32BU_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi8_scratch ADDRri:$addr)), (L32BU_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi16_scratch ADDRri:$addr)), (L32SU_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(f32 (ScratchpadLoad ADDRri:$addr)), (L32W_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- scalar f32 load-&amp;gt; i32 load ----------------//&lt;br /&gt;
// Scalar store to 32-bit registers &lt;br /&gt;
def : Pat&amp;lt;(MemStore f32:$dstsrc, ADDRri:$addr), (S32W_Mainmem f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore f32:$dstsrc, ADDRri:$addr), (S32W_Scratchpad f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- vector load and store ----------------//&lt;br /&gt;
//---------------- intrinsics load and store ----------------//&lt;br /&gt;
//integer&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16i8 ADDRri:$addr)), (v16i32 (LV32BMainmem_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16i8_scratchpad ADDRri:$addr)), (v16i32 (LV32BScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16u8 ADDRri:$addr)), (v16i32 (LV32BUMainmem_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16u8_scratchpad ADDRri:$addr)), (v16i32 (LV32BUScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16i16 ADDRri:$addr)), (v16i32 (LV32SMainmem_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16i16_scratchpad ADDRri:$addr)), (v16i32 (LV32SScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16u16 ADDRri:$addr)), (v16i32 (LV32SUMainmem_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16u16_scratchpad ADDRri:$addr)), (v16i32 (LV32SUScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_block_loadv16i32_scratchpad ADDRri:$addr)), (v16i32 (LV32WScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(int_npu_block_storev16i8 ADDRri:$addr, v16i32:$dstsrc), (SV32BMainmem_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_npu_block_storev16i8_scratchpad ADDRri:$addr, v16i32:$dstsrc), (SV32BScratchpad_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_npu_block_storev16i16 ADDRri:$addr, v16i32:$dstsrc), (SV32SMainmem_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_npu_block_storev16i16_scratchpad ADDRri:$addr, v16i32:$dstsrc), (SV32SScratchpad_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_npu_block_storev16i32_scratchpad ADDRri:$addr, v16i32:$dstsrc), (SV32WScratchpad_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//float&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (int_npu_block_loadv16f32_scratchpad ADDRri:$addr)), (LV32WScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (int_npu_block_loadv16f32_masked ADDRri:$addr)), (LV32WMainmem_M ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (int_npu_block_loadv16f32_scratchpad_masked ADDRri:$addr)), (LV32WScratchpad_M ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(int_npu_block_storev16f32_scratchpad ADDRri:$addr, v16f32:$dstsrc), (SV32WScratchpad_U v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_npu_block_storev16f32_masked ADDRri:$addr, v16f32:$dstsrc), (SV32WMainmem_M v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_npu_block_storev16f32_scratchpad_masked ADDRri:$addr, v16f32:$dstsrc), (SV32WScratchpad_M v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Float gather/scatter&lt;br /&gt;
def : Pat&amp;lt;(int_npu_gather_loadf32_scratchpad V16ADDRri:$addr), (GLV32WScratchpad_U V16ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_npu_gather_loadf32_scratchpad_masked V16ADDRri:$addr), (GLV32WScratchpad_M V16ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(int_npu_scatter_storef32_scratchpad V16ADDRri:$addr, v16f32:$srcDest), (SSV32WScratchpad_U v16f32:$srcDest, V16ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_npu_scatter_storef32_scratchpad_masked V16ADDRri:$addr, v16f32:$srcDest), (SSV32WScratchpad_M v16f32:$srcDest, V16ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- vector anyextload -&amp;gt; sextload ----------------//&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (anyextloadv16i8_mem ADDRri:$addr)), (LV32BMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (anyextloadv16i8_scratch ADDRri:$addr)), (LV32BScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (anyextloadv16i16_mem ADDRri:$addr)), (LV32SMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (anyextloadv16i16_scratch ADDRri:$addr)), (LV32SScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- vector load/store -&amp;gt; sextload/truncstore ----------------//&lt;br /&gt;
def : Pat&amp;lt;(v16i8 (MemLoad ADDRri:$addr)),  (LV32BMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i8 (ScratchpadLoad ADDRri:$addr)),  (LV32BScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i16 (MemLoad ADDRri:$addr)), (LV32SMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i16 (ScratchpadLoad ADDRri:$addr)), (LV32SScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (ScratchpadLoad ADDRri:$addr)), (LV32WScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(MemStore v16i8:$dstsrc, ADDRri:$addr),  (SV32BMainmem_U v16i8:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(MemStore v16i16:$dstsrc, ADDRri:$addr), (SV32SMainmem_U v16i16:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore v16i8:$dstsrc, ADDRri:$addr),  (SV32BScratchpad_U v16i8:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore v16i16:$dstsrc, ADDRri:$addr), (SV32SScratchpad_U v16i16:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore v16i32:$dstsrc, ADDRri:$addr), (SV32WScratchpad_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (MemLoad ADDRri:$addr)), (LV32WMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (ScratchpadLoad ADDRri:$addr)), (LV32WScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(MemStore v16f32:$dstsrc, ADDRri:$addr), (SV32WMainmem_U v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore v16f32:$dstsrc, ADDRri:$addr), (SV32WScratchpad_U v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Questi pattern servono per gestire i tipi di dato vettoriali di dim &amp;lt; 512 bits&lt;br /&gt;
// v16i8 &amp;lt;=&amp;gt; v16i32&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (bitconvert v16i8:$src)), (v16i32 (SEXT8_32VV_U v16i8:$src))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(MemStore (v16i8 (bitconvert v16i32:$src)), ADDRri:$addr), (SV32BMainmem_U v16i32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore (v16i8 (bitconvert v16i32:$src)), ADDRri:$addr), (SV32BScratchpad_U v16i32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
// v16i16 &amp;lt;=&amp;gt; v16i32&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (bitconvert v16i16:$src)), (v16i32 (SEXT16_32VV_U v16i16:$src))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(MemStore (v16i16 (bitconvert v16i32:$src)), ADDRri:$addr), (SV32SMainmem_U v16i32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore (v16i16 (bitconvert v16i32:$src)), ADDRri:$addr), (SV32SScratchpad_U v16i32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// v8f32 &amp;lt;=&amp;gt; v16f32&lt;br /&gt;
//def : Pat&amp;lt;(MemStore (v8f32 (extract_subvector v16f32:$src, (i32 0))), ADDRri:$addr), (SV32WMainmem_U v16f32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
//def : Pat&amp;lt;(ScratchpadStore (v8f32 (extract_subvector v16f32:$src, (i32 0))), ADDRri:$addr), (SV32WScratchpad_U v16f32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//---------------- Patterns for type conversions ----------------//&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Sign Extension Patterns sext_inreg -&amp;gt; sext&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (sext_inreg v16i32:$src, v16i8)), (v16i32 (SEXT8_32VV_U v16i32:$src))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (sext_inreg v16i32:$src, v16i16)), (v16i32 (SEXT16_32VV_U v16i32:$src))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// BITCAST patterns&lt;br /&gt;
def : Pat&amp;lt;(f32 (bitconvert (i32 GPR32:$src))), (f32 GPR32:$src)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (bitconvert (f32 GPR32:$src))), (i32 GPR32:$src)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (bitconvert (v16i32 VR512W:$src))), (v16f32 VR512W:$src)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (bitconvert (v16f32 VR512W:$src))), (v16i32 VR512W:$src)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// CLZ and CTZ Intrinsics&lt;br /&gt;
def : Pat&amp;lt;(i32 (int_npu_clzi32 i32:$src)),&lt;br /&gt;
(i32 (CLZSS_32 i32:$src))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_clzv16i32 v16i32:$src)),&lt;br /&gt;
(v16i32 (CLZVV_U_32 v16i32:$src))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(i32 (int_npu_ctzi32 i32:$src)),&lt;br /&gt;
(i32 (CTZSS_32 i32:$src))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_npu_ctzv16i32 v16i32:$src)),&lt;br /&gt;
(v16i32 (CTZVV_U_32 v16i32:$src))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Integer division&lt;br /&gt;
// v16i32&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (sdiv v16i32:$src1, v16i32:$src2)),&lt;br /&gt;
    (F32TOI32_VV_U (DIVFVVV_U_32 (I32TOF32_VV_U v16i32:$src1), (I32TOF32_VV_U v16i32:$src2)))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Branch patterns&lt;br /&gt;
def : Pat&amp;lt;(brcond (i32 (setne i32:$lhs, 0)), bb:$addr), (BNEZ i32:$lhs, bb:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(brcond (i32 (seteq i32:$lhs, 0)), bb:$addr), (BEQZ i32:$lhs, bb:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(brcond i32:$lhs, bb:$addr), (BNEZ i32:$lhs, bb:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Call patterns&lt;br /&gt;
def : Pat&amp;lt;(call tglobaladdr:$addr), (JMPSR_OFF tglobaladdr:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(call texternalsym:$addr), (JMPSR_OFF texternalsym:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// GetLane patterns&lt;br /&gt;
def : Pat&amp;lt;(extractelt v16f32:$src0, i32:$src1),&lt;br /&gt;
          (GET_LANEI_32 v16f32:$src0, i32:$src1)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(extractelt v16f32:$src, simm9:$imm),&lt;br /&gt;
          (GET_LANEIimm v16f32:$src, imm:$imm)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// ISD Nodes Patterns&lt;br /&gt;
def : Pat&amp;lt;(i32 (leah tglobaladdr:$addr)), (LEAH tglobaladdr:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leal i32:$addrh, tglobaladdr:$addr)), (LEAL i32:$addrh, tglobaladdr:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leah tconstpool:$addr)), (LEAH tconstpool:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leal i32:$addrh, tconstpool:$addr)), (LEAL i32:$addrh, tconstpool:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leah tblockaddress:$addr)), (LEAH tblockaddress:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leal i32:$addrh, tblockaddress:$addr)), (LEAL i32:$addrh, tblockaddress:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leah tjumptable:$addr)), (LEAH tjumptable:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leal i32:$addrh, tjumptable:$addr)), (LEAL i32:$addrh, tjumptable:$addr)&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUInstrInfo.td&amp;diff=2133</id>
		<title>NaplesPUInstrInfo.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUInstrInfo.td&amp;diff=2133"/>
				<updated>2019-06-21T15:01:52Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusInstrInfo.td to NaplesPUInstrInfo.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
NuPlusInstrInfo.td and [[NuPlusInstrFormats.td]] describe the nu+ instructions and the patterns to transform LLVM IR into machine code. The NuPlusInstrInfo.td contains the instructions definition and the patterns necessary for the translation from the LLVM IR to the nu+ machine code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusInstrInfo.td - Target Description for NuPlus Target -----------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This file describes the NuPlus instructions in TableGen format.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Instruction format superclass&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
include &amp;quot;NuPlusInstrFormats.td&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Instruction definition&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Arithmetic Instructions (Format R &amp;amp; I)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//Arithmetic Integer Two operands&lt;br /&gt;
defm OR     : FArithInt_TwoOp&amp;lt;&amp;quot;or&amp;quot;, or, 1&amp;gt;;&lt;br /&gt;
defm AND    : FArithInt_TwoOp&amp;lt;&amp;quot;and&amp;quot;, and, 2&amp;gt;;&lt;br /&gt;
defm XOR    : FArithInt_TwoOp&amp;lt;&amp;quot;xor&amp;quot;, xor, 3&amp;gt;;&lt;br /&gt;
defm ADD    : FArithInt_TwoOp&amp;lt;&amp;quot;add&amp;quot;, add, 4&amp;gt;;&lt;br /&gt;
defm SUB    : FArithInt_TwoOp&amp;lt;&amp;quot;sub&amp;quot;, sub, 5&amp;gt;;&lt;br /&gt;
defm MULL   : FArithInt_TwoOp&amp;lt;&amp;quot;mull&amp;quot;, mul, 6&amp;gt;;&lt;br /&gt;
defm MULH   : FArithInt_TwoOp&amp;lt;&amp;quot;mulhs&amp;quot;, mulhs, 7&amp;gt;;&lt;br /&gt;
defm MULHU  : FArithInt_TwoOp&amp;lt;&amp;quot;mulhu&amp;quot;, mulhu, 8&amp;gt;;&lt;br /&gt;
defm SRA    : FSRInt_TwoOp&amp;lt;&amp;quot;ashr&amp;quot;, sra, 9&amp;gt;;&lt;br /&gt;
defm SRL    : FSRInt_TwoOp&amp;lt;&amp;quot;shr&amp;quot;, srl, 10&amp;gt;;&lt;br /&gt;
defm SLL    : FSRInt_TwoOp&amp;lt;&amp;quot;shl&amp;quot;, shl, 11&amp;gt;;&lt;br /&gt;
//Arithmetic Integer One operand&lt;br /&gt;
defm CLZ    : FArithInt_OneOp&amp;lt;&amp;quot;clz&amp;quot;, ctlz, 12&amp;gt;;&lt;br /&gt;
defm CTZ    : FArithInt_OneOp&amp;lt;&amp;quot;ctz&amp;quot;, cttz, 13&amp;gt;;&lt;br /&gt;
//Compare Integer&lt;br /&gt;
defm SEQSI : FCompInt&amp;lt;&amp;quot;cmpeq&amp;quot;, SETEQ, 14, int_nuplus_mask_cmpi32_eq&amp;gt;;//, int_nuplus_mask_cmpi64_eq&amp;gt;;&lt;br /&gt;
defm SNESI : FCompInt&amp;lt;&amp;quot;cmpne&amp;quot;, SETNE, 15, int_nuplus_mask_cmpi32_ne&amp;gt;;//, int_nuplus_mask_cmpi64_ne&amp;gt;;&lt;br /&gt;
defm SGTSI : FCompInt&amp;lt;&amp;quot;cmpgt&amp;quot;, SETGT, 16, int_nuplus_mask_cmpi32_sgt&amp;gt;;//, int_nuplus_mask_cmpi64_sgt&amp;gt;;&lt;br /&gt;
defm SGESI : FCompInt&amp;lt;&amp;quot;cmpge&amp;quot;, SETGE, 17, int_nuplus_mask_cmpi32_sge&amp;gt;;//, int_nuplus_mask_cmpi64_sge&amp;gt;;&lt;br /&gt;
defm SLTSI : FCompInt&amp;lt;&amp;quot;cmplt&amp;quot;, SETLT, 18, int_nuplus_mask_cmpi32_slt&amp;gt;;//, int_nuplus_mask_cmpi64_slt&amp;gt;;&lt;br /&gt;
defm SLESI : FCompInt&amp;lt;&amp;quot;cmple&amp;quot;, SETLE, 19, int_nuplus_mask_cmpi32_sle&amp;gt;;//, int_nuplus_mask_cmpi64_sle&amp;gt;;&lt;br /&gt;
//Compare Unsigned&lt;br /&gt;
defm SGTUI : FCompInt&amp;lt;&amp;quot;cmpugt&amp;quot;, SETUGT, 20, int_nuplus_mask_cmpi32_ugt&amp;gt;;//, int_nuplus_mask_cmpi64_ugt&amp;gt;;&lt;br /&gt;
defm SGEUI : FCompInt&amp;lt;&amp;quot;cmpuge&amp;quot;, SETUGE, 21, int_nuplus_mask_cmpi32_uge&amp;gt;;//, int_nuplus_mask_cmpi64_uge&amp;gt;;&lt;br /&gt;
defm SLTUI : FCompInt&amp;lt;&amp;quot;cmpult&amp;quot;, SETULT, 22, int_nuplus_mask_cmpi32_ult&amp;gt;;//, int_nuplus_mask_cmpi64_ult&amp;gt;;&lt;br /&gt;
defm SLEUI : FCompInt&amp;lt;&amp;quot;cmpule&amp;quot;, SETULE, 23, int_nuplus_mask_cmpi32_ule&amp;gt;;//, int_nuplus_mask_cmpi64_ule&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Cross Product Instruction&lt;br /&gt;
def CROSSPROD_32 : FR_TwoOp_Unmasked_32 &amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
  &amp;quot;crp $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
  [(set v16i32:$dst, (int_nuplus_crossprodv16i32 v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
  63,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Shuffle&lt;br /&gt;
def SHUFFLEI_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
  &amp;quot;shuffle_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
  [(set v16i32:$dst, (int_nuplus_shufflei32 v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
  24,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Get lane&lt;br /&gt;
def GET_LANEI_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
  &amp;quot;getlane_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, (extractelt v16i32:$src0, i32:$src1))],&lt;br /&gt;
  25,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def GET_LANEIimm : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins VR512W:$src, SIMM9OP:$imm),&lt;br /&gt;
  &amp;quot;getlanei $dst, $src, $imm&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, (extractelt v16i32:$src, simm9:$imm))],&lt;br /&gt;
  25,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Move register - register&lt;br /&gt;
def MOVE_SS_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [],&lt;br /&gt;
  32,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def MOVE_VS_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set v16i32:$dst, (splat i32:$src0))],&lt;br /&gt;
  32,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def MOVE_VV_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0),&lt;br /&gt;
  &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [],&lt;br /&gt;
  32,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
let Constraints = &amp;quot;$dst = $oldvalue&amp;quot;, isAsmParserOnly=1 in {&lt;br /&gt;
&lt;br /&gt;
  def MOVE_VS_M_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins GPR32:$src0, VR512W:$oldvalue),&lt;br /&gt;
    &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_nuplus_vector_mixi32 (splat i32:$src0), v16i32:$oldvalue))],&lt;br /&gt;
    32,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def MOVE_VV_M_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
    &amp;quot;move_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_nuplus_vector_mixi32 v16i32:$src0, v16i32:$oldvalue))],&lt;br /&gt;
    32,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Arithmetic Float Two operands&lt;br /&gt;
defm ADDF   : FArithFloat_TwoOp&amp;lt;&amp;quot;fadd&amp;quot;, fadd, 33&amp;gt;;&lt;br /&gt;
defm SUBF   : FArithFloat_TwoOp&amp;lt;&amp;quot;fsub&amp;quot;, fsub, 34&amp;gt;;&lt;br /&gt;
defm MULF   : FArithFloat_TwoOp&amp;lt;&amp;quot;fmul&amp;quot;, fmul, 35&amp;gt;;&lt;br /&gt;
defm DIVF   : FArithFloat_TwoOp&amp;lt;&amp;quot;fdiv&amp;quot;, fdiv, 36&amp;gt;;&lt;br /&gt;
//Compare Float&lt;br /&gt;
def FloatCompareType: SDTypeProfile&amp;lt;1, 2, [&lt;br /&gt;
  SDTCisInt&amp;lt;0&amp;gt;, SDTCisFP&amp;lt;1&amp;gt;, SDTCisSameAs&amp;lt;1, 2&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
def FGT: SDNode&amp;lt;&amp;quot;NuPlusISD::FGT&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FGE: SDNode&amp;lt;&amp;quot;NuPlusISD::FGE&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FLT: SDNode&amp;lt;&amp;quot;NuPlusISD::FLT&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FLE: SDNode&amp;lt;&amp;quot;NuPlusISD::FLE&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FEQ: SDNode&amp;lt;&amp;quot;NuPlusISD::FEQ&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
def FNE: SDNode&amp;lt;&amp;quot;NuPlusISD::FNE&amp;quot;, FloatCompareType&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
defm SEQFO : FCompFloat&amp;lt;&amp;quot;cmpfeq&amp;quot;, FEQ, 37, int_nuplus_mask_cmpf32_eq&amp;gt;;//, int_nuplus_mask_cmpf64_eq&amp;gt;;&lt;br /&gt;
defm SNEFO : FCompFloat&amp;lt;&amp;quot;cmpfne&amp;quot;, FNE, 38, int_nuplus_mask_cmpf32_ne&amp;gt;;//, int_nuplus_mask_cmpf64_ne&amp;gt;;&lt;br /&gt;
defm SGTFO : FCompFloat&amp;lt;&amp;quot;cmpfgt&amp;quot;, FGT, 39, int_nuplus_mask_cmpf32_gt&amp;gt;;//, int_nuplus_mask_cmpf64_gt&amp;gt;;&lt;br /&gt;
defm SGEFO : FCompFloat&amp;lt;&amp;quot;cmpfge&amp;quot;, FGE, 40, int_nuplus_mask_cmpf32_ge&amp;gt;;//, int_nuplus_mask_cmpf64_ge&amp;gt;;&lt;br /&gt;
defm SLTFO : FCompFloat&amp;lt;&amp;quot;cmpflt&amp;quot;, FLT, 41, int_nuplus_mask_cmpf32_lt&amp;gt;;//, int_nuplus_mask_cmpf64_lt&amp;gt;;&lt;br /&gt;
defm SLEFO : FCompFloat&amp;lt;&amp;quot;cmpfle&amp;quot;, FLE, 42, int_nuplus_mask_cmpf32_le&amp;gt;;//, int_nuplus_mask_cmpf64_le&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//sign extension&lt;br /&gt;
defm SEXT8_32 : FSext_32&amp;lt;&amp;quot;sext8&amp;quot;, i8, 43, v16i8&amp;gt;;&lt;br /&gt;
defm SEXT16_32 : FSext_32&amp;lt;&amp;quot;sext16&amp;quot;, i16, 44, v16i16&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Integer to Float conversion&lt;br /&gt;
def I32TOF32_SS : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;itof_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set f32:$dst, (sint_to_fp i32:$src0))],&lt;br /&gt;
  48,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def I32TOF32_VV_U : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0),&lt;br /&gt;
  &amp;quot;itof_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set v16f32:$dst, (sint_to_fp v16i32:$src0))],&lt;br /&gt;
  48,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
  def I32TOF32_VV_M : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
    &amp;quot;itof_i32.m $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (int_nuplus_vector_mixf32 (sint_to_fp v16i32:$src0), v16f32:$oldvalue))],&lt;br /&gt;
    48,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Float to Integer conversion&lt;br /&gt;
def F32TOI32_SS : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;ftoi_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, (fp_to_sint f32:$src0))],&lt;br /&gt;
  49,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def F32TOI32_VV_U : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
  (outs VR512W:$dst),&lt;br /&gt;
  (ins VR512W:$src0),&lt;br /&gt;
  &amp;quot;ftoi_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set v16i32:$dst, (fp_to_sint v16f32:$src0))],&lt;br /&gt;
  49,&lt;br /&gt;
  Fmt_V,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
  def F32TOI32_VV_M : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
    &amp;quot;ftoi_i32.m $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_nuplus_vector_mixi32 (fp_to_sint v16f32:$src0), v16i32:$oldvalue))],&lt;br /&gt;
    49,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// MOVEI Instructions (Format MOVEI)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
defm MOVEIL : FMOVEI_ALL&amp;lt;&amp;quot;moveil&amp;quot;, 0&amp;gt;;&lt;br /&gt;
defm MOVEIH : FMOVEI_ALL&amp;lt;&amp;quot;moveih&amp;quot;, 1&amp;gt;;&lt;br /&gt;
defm MOVEI : FMOVEI_ALL&amp;lt;&amp;quot;movei&amp;quot;, 2&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// LOAD/STORE SPECIAL REGISTERS&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def READMR  : READ_SPR&amp;lt;MaskReg, &amp;quot;read_mr&amp;quot;, int_nuplus_read_mask_reg&amp;gt;;&lt;br /&gt;
def WRITEMR : WRITE_SPR&amp;lt;MaskReg, &amp;quot;write_mr&amp;quot;, int_nuplus_write_mask_reg&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Create Mask Instruction&lt;br /&gt;
def CREATEMASK_32 : FR_OneOp_Unmasked_32 &amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins VR512W:$src0),&lt;br /&gt;
  &amp;quot;crt_mask_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, (int_nuplus_createmaskv16i32 v16i32:$src0))],&lt;br /&gt;
  50,&lt;br /&gt;
  Fmt_S,&lt;br /&gt;
  Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// MEM Instructions (Format M)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// Scalar load to 32-bit registers&lt;br /&gt;
defm L32BS : FMLoadScalar_32&amp;lt;&amp;quot;_s8&amp;quot;, sextloadi8_mem, sextloadi8_scratch, 0&amp;gt;;&lt;br /&gt;
defm L32SS : FMLoadScalar_32&amp;lt;&amp;quot;_s16&amp;quot;, sextloadi16_mem, sextloadi16_scratch, 1&amp;gt;;&lt;br /&gt;
defm L32W  : FMLoadScalar_32&amp;lt;&amp;quot;&amp;quot;, MemLoad, ScratchpadLoad, 2&amp;gt;;&lt;br /&gt;
defm L32BU : FMLoadScalar_32&amp;lt;&amp;quot;_u8&amp;quot;, zextloadi8_mem, zextloadi8_scratch, 4&amp;gt;;&lt;br /&gt;
defm L32SU : FMLoadScalar_32&amp;lt;&amp;quot;_u16&amp;quot;, zextloadi16_mem, zextloadi16_scratch, 5&amp;gt;;&lt;br /&gt;
defm S32B : FMStoreScalar_32&amp;lt;&amp;quot;_8&amp;quot;, truncstorei8_mem, truncstorei8_scratch, 32&amp;gt;;&lt;br /&gt;
defm S32S : FMStoreScalar_32&amp;lt;&amp;quot;_16&amp;quot;, truncstorei16_mem, truncstorei16_scratch, 33&amp;gt;;&lt;br /&gt;
defm S32W : FMStoreScalar_32&amp;lt;&amp;quot;&amp;quot;, MemStore, ScratchpadStore, 34&amp;gt;;&lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
//Vector load block &lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
&lt;br /&gt;
// Vector load to 32-bit registers&lt;br /&gt;
defm LV32B : FMLoadVector_32&amp;lt;&amp;quot;_v16i8&amp;quot;, sextloadv16i8_mem, sextloadv16i8_scratch, &lt;br /&gt;
                              int_nuplus_block_loadv16i8_masked, int_nuplus_block_loadv16i8_scratchpad_masked, &lt;br /&gt;
                              7&amp;gt;;&lt;br /&gt;
defm LV32S : FMLoadVector_32&amp;lt;&amp;quot;_v16i16&amp;quot;, sextloadv16i16_mem, sextloadv16i16_scratch, &lt;br /&gt;
                              int_nuplus_block_loadv16i16_masked, int_nuplus_block_loadv16i16_scratchpad_masked, &lt;br /&gt;
                              8&amp;gt;;&lt;br /&gt;
defm LV32W : FMLoadVector_32&amp;lt;&amp;quot;_v16i32&amp;quot;, MemLoad, ScratchpadLoad, &lt;br /&gt;
                              int_nuplus_block_loadv16i32_masked, int_nuplus_block_loadv16i32_scratchpad_masked, &lt;br /&gt;
                              9&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
defm LV32BU : FMLoadVector_32&amp;lt;&amp;quot;_v16u8&amp;quot;, zextloadv16i8_mem, zextloadv16i8_scratch, &lt;br /&gt;
                              int_nuplus_block_loadv16u8_masked, int_nuplus_block_loadv16u8_scratchpad_masked, &lt;br /&gt;
                              11&amp;gt;;&lt;br /&gt;
defm LV32SU : FMLoadVector_32&amp;lt;&amp;quot;_v16u16&amp;quot;, zextloadv16i16_mem, zextloadv16i16_scratch, &lt;br /&gt;
                              int_nuplus_block_loadv16u16_masked, int_nuplus_block_loadv16u16_scratchpad_masked, &lt;br /&gt;
                              12&amp;gt;;&lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
//Vector load gather &lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
&lt;br /&gt;
// Vector gather to 32-bit registers&lt;br /&gt;
defm GLV32W : FMGather_32&amp;lt;&amp;quot;32&amp;quot;, int_nuplus_gather_loadi32_scratchpad,&lt;br /&gt;
                          int_nuplus_gather_loadi32_scratchpad_masked,&lt;br /&gt;
                          16&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
//Vector store block &lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
&lt;br /&gt;
// Vector store from 32-bit registers&lt;br /&gt;
defm SV32B : FMStoreVector_32&amp;lt;&amp;quot;_v16i8&amp;quot;, truncstorev16i8_mem, truncstorev16i8_scratch, &lt;br /&gt;
                              int_nuplus_block_storev16i8_masked, int_nuplus_block_storev16i8_scratchpad_masked, &lt;br /&gt;
                              36&amp;gt;;&lt;br /&gt;
defm SV32S : FMStoreVector_32&amp;lt;&amp;quot;_v16i16&amp;quot;, truncstorev16i16_mem, truncstorev16i16_scratch, &lt;br /&gt;
                              int_nuplus_block_storev16i16_masked, int_nuplus_block_storev16i16_scratchpad_masked, &lt;br /&gt;
                              37&amp;gt;;&lt;br /&gt;
defm SV32W : FMStoreVector_32&amp;lt;&amp;quot;_v16i32&amp;quot;, MemStore, ScratchpadStore, &lt;br /&gt;
                              int_nuplus_block_storev16i32_masked, int_nuplus_block_storev16i32_scratchpad_masked, &lt;br /&gt;
                              38&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
//Vector store scatter &lt;br /&gt;
//--------------------------------------------------------------------------------//&lt;br /&gt;
&lt;br /&gt;
// Vector scatter from 32-bit registers&lt;br /&gt;
defm SSV32W : FMScatter_32&amp;lt;&amp;quot;32&amp;quot;,int_nuplus_scatter_storei32_scratchpad, &lt;br /&gt;
                              int_nuplus_scatter_storei32_scratchpad_masked, &lt;br /&gt;
                              42&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Jump and Branch Instructions (Format J/JR)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
let isTerminator = 1 in {&lt;br /&gt;
  //Unconditional jump with offset, PC:=PC+addr&lt;br /&gt;
  def JMP : FJ&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins brtarget:$addr),&lt;br /&gt;
    &amp;quot;jmp $addr&amp;quot;,&lt;br /&gt;
    [(br bb:$addr)],&lt;br /&gt;
    0&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    let isBarrier = 1;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  //Unconditional jump with register PC:=DST&lt;br /&gt;
  def JUMPREG : FJR&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins GPR32:$cond),&lt;br /&gt;
  &amp;quot;jmp $cond&amp;quot;,&lt;br /&gt;
  [(brind i32:$cond)],&lt;br /&gt;
  0&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    let isBranch = 1;&lt;br /&gt;
    let isIndirectBranch = 1;&lt;br /&gt;
    let isBarrier = 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Return PC:=RA&lt;br /&gt;
  def JRET : FJR&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins),&lt;br /&gt;
  &amp;quot;jret&amp;quot;,&lt;br /&gt;
  [(return)],&lt;br /&gt;
  3&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    let Inst{23-18} = 0;&lt;br /&gt;
    let Inst{17-0} = 0;&lt;br /&gt;
&lt;br /&gt;
    let isReturn = 1;&lt;br /&gt;
    let isTerminator = 1;&lt;br /&gt;
    let isBarrier = 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //Conditional Branch&lt;br /&gt;
  def BEQZ : FJR&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$cond, brtarget:$addr),&lt;br /&gt;
    &amp;quot;beqz $cond, $addr&amp;quot;,&lt;br /&gt;
    [],&lt;br /&gt;
    5&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  //Conditional Branch&lt;br /&gt;
  def BNEZ : FJR&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$cond, brtarget:$addr),&lt;br /&gt;
    &amp;quot;bnez $cond, $addr&amp;quot;,&lt;br /&gt;
    [],&lt;br /&gt;
    6&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
let isCall = 1, Defs = [ RA_REG ] in {&lt;br /&gt;
  //Jump with offset and save return address RA:=PC+4, PC:=PC+addr&lt;br /&gt;
  def JMPSR_OFF : FJ&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins calltarget:$addr, variable_ops),&lt;br /&gt;
    &amp;quot;jmpsr $addr&amp;quot;,&lt;br /&gt;
    [],&lt;br /&gt;
    1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  //Jump with register and save return address RA:=PC+4, PC:=DST&lt;br /&gt;
  def JMPSR_REG : FJR&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$dst, variable_ops),&lt;br /&gt;
    &amp;quot;jmpsr $dst&amp;quot;,&lt;br /&gt;
    [(call i32:$dst)],&lt;br /&gt;
    1&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
    let Inst{23-18} = dst;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Control Instructions (Format C)&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def BARRIER : FC&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
  &amp;quot;barrier $src0, $src1&amp;quot;,&lt;br /&gt;
  [(int_nuplus_barrier i32:$src0, i32:$src1)],&lt;br /&gt;
  0&amp;gt;;&lt;br /&gt;
  &lt;br /&gt;
def FLUSH : FC&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins GPR32:$src0),&lt;br /&gt;
  &amp;quot;flush $src0&amp;quot;,&lt;br /&gt;
  [(int_nuplus_flush i32:$src0)],&lt;br /&gt;
  2&amp;gt;{&lt;br /&gt;
    let Inst{17-12} = 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
// READ Control Register&lt;br /&gt;
def READCR : FC&amp;lt;&lt;br /&gt;
  (outs GPR32:$src0),&lt;br /&gt;
  (ins GPR32:$src1),&lt;br /&gt;
  &amp;quot;read_cr $src0, $src1&amp;quot;,&lt;br /&gt;
  [(set i32:$src0, (int_nuplus_read_control_reg i32:$src1))],&lt;br /&gt;
  3&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// WRITE Control Register&lt;br /&gt;
def WRITECR : FC&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
  &amp;quot;write_cr $src0, $src1&amp;quot;,&lt;br /&gt;
  [(int_nuplus_write_control_reg i32:$src0, i32:$src1)],&lt;br /&gt;
  4&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Miscellaneous Instructions&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def NOP : InstNuPlus&amp;lt;&lt;br /&gt;
  (outs),&lt;br /&gt;
  (ins),&lt;br /&gt;
  &amp;quot;nop&amp;quot;,&lt;br /&gt;
  []&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  let Inst{31-0} = 0xffffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def LOAD_EFFECTIVE_ADDR : InstNuPlus&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins LEAri:$addr),&lt;br /&gt;
  &amp;quot;_lea $dst, $addr&amp;quot;,&lt;br /&gt;
  [(set i32:$dst, ADDRri:$addr)]&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  let isAsmParserOnly = 1;   // Don't disassemble&lt;br /&gt;
&lt;br /&gt;
  bits&amp;lt;16&amp;gt; addr;&lt;br /&gt;
  bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-29} = 0b010;&lt;br /&gt;
  let Inst{28-24} = 4;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-2} = addr;&lt;br /&gt;
  let Inst{1} = 0;&lt;br /&gt;
  let Inst{0} = 0;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//TODO: (Catello) Add symbol in NuPlusAsmParser::ProcessInstruction.&lt;br /&gt;
// This node defines the lea pseudo-instruction that can be used in&lt;br /&gt;
// assembly files.&lt;br /&gt;
def LOAD_EFFECTIVE_ADDR_SYM : InstNuPlus&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins symref:$label),&lt;br /&gt;
  &amp;quot;lea $dst, $label&amp;quot;,&lt;br /&gt;
  []&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  let isPseudo = 1;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def LEAH : InstNuPlus&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins ABSh:$addr),&lt;br /&gt;
  &amp;quot;leah $dst, $addr&amp;quot;,&lt;br /&gt;
  []&amp;gt; {&lt;br /&gt;
  let isAsmParserOnly = 1;   // Don't disassemble&lt;br /&gt;
&lt;br /&gt;
  bits&amp;lt;16&amp;gt; addr;&lt;br /&gt;
  bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-27} = 0b01100; // Format MOVEI&lt;br /&gt;
  let Inst{26-24} = 1; //Opcode MOVEI&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-2} = addr;&lt;br /&gt;
  let Inst{1} = 0;&lt;br /&gt;
  let Inst{0} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def LEAL : InstNuPlus&amp;lt;&lt;br /&gt;
  (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$addrh, ABSl:$addr),&lt;br /&gt;
  &amp;quot;leal $dst, $addr&amp;quot;,&lt;br /&gt;
  []&amp;gt; {&lt;br /&gt;
  let isAsmParserOnly = 1;   // Don't disassemble&lt;br /&gt;
  &lt;br /&gt;
  //costraint used to let llvm use the same destination register as leah&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $addrh&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
  bits&amp;lt;16&amp;gt; addr;&lt;br /&gt;
  bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-27} = 0b01100; // Format MOVEI&lt;br /&gt;
  let Inst{26-24} = 0; //Opcode MOVEI&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-2} = addr;&lt;br /&gt;
  let Inst{1} = 0;&lt;br /&gt;
  let Inst{0} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Pseudo instructions&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// These pseudo ops capture outgoing argument space on the stack and will be removed&lt;br /&gt;
// by later passes.&lt;br /&gt;
let Defs = [ SP_REG ], Uses = [ SP_REG ], hasSideEffects = 1 in {&lt;br /&gt;
   def ADJCALLSTACKDOWN : Pseudo&amp;lt;&lt;br /&gt;
     (outs),&lt;br /&gt;
     (ins i32imm:$amt1, i32imm:$amt2),&lt;br /&gt;
     [(callseq_start timm:$amt1, timm:$amt2)]&amp;gt;;&lt;br /&gt;
 &lt;br /&gt;
   def ADJCALLSTACKUP : Pseudo&amp;lt;&lt;br /&gt;
     (outs),&lt;br /&gt;
     (ins i32imm:$amt1, i32imm:$amt2),&lt;br /&gt;
     [(callseq_end timm:$amt1, timm:$amt2)]&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// SELECT pseudo instructions. This architecture doesn't actually have a scalar&lt;br /&gt;
// conditional move instruction. These will be replaced in a later pass&lt;br /&gt;
// with a diamond pattern of conditional branches.&lt;br /&gt;
//&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def SELECTI : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$pred, GPR32:$true, GPR32:$false),&lt;br /&gt;
    [(set i32:$dst, (selcondresult i32:$pred, i32:$true, i32:$false))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def SELECTF : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$pred, GPR32:$true, GPR32:$false),&lt;br /&gt;
    [(set f32:$dst, (selcondresult i32:$pred, f32:$true, f32:$false))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def SELECTVI : Pseudo&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins GPR32:$pred, VR512W:$true, VR512W:$false),&lt;br /&gt;
    [(set v16i32:$dst, (selcondresult i32:$pred, v16i32:$true, v16i32:$false))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def SELECTVF : Pseudo&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins GPR32:$pred, VR512W:$true, VR512W:$false),&lt;br /&gt;
    [(set v16f32:$dst, (selcondresult i32:$pred, v16f32:$true, v16f32:$false))]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def LoadI32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$val),&lt;br /&gt;
    [(set i32:$dst, (i32 imm:$val))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def LoadF32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$val),&lt;br /&gt;
    [(set f32:$dst, (f32 fpimm:$val))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def InsertELT32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$vec, GPR32:$elem, GPR32:$pos),&lt;br /&gt;
    [(set v16i32:$dst, (insert_elt v16i32:$vec, i32:$elem, i32:$pos))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def : Pat &amp;lt;(v16f32 (insert_elt v16f32:$vec, f32:$elem, i32:$pos)), (v16f32 (InsertELT32 v16f32:$vec, f32:$elem, i32:$pos))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Atomics&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
 defm ATOMIC_LOAD_ADD : AtomicBinary&amp;lt;atomic_load_add&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_SUB : AtomicBinary&amp;lt;atomic_load_sub&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_AND : AtomicBinary&amp;lt;atomic_load_and&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_OR  : AtomicBinary&amp;lt;atomic_load_or&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_XOR : AtomicBinary&amp;lt;atomic_load_xor&amp;gt;;&lt;br /&gt;
 defm ATOMIC_LOAD_NAND : AtomicBinary&amp;lt;atomic_load_nand&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def ATOMIC_CMP_SWAP : Pseudo&amp;lt;&lt;br /&gt;
   (outs GPR32:$dst),&lt;br /&gt;
   (ins GPR32:$ptr, GPR32:$cmp, GPR32:$swap),&lt;br /&gt;
   [(set i32:$dst, (atomic_cmp_swap GPR32:$ptr, GPR32:$cmp, GPR32:$swap))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
 def ATOMIC_SWAP : Pseudo&amp;lt;&lt;br /&gt;
   (outs GPR32:$dst),&lt;br /&gt;
  (ins GPR32:$ptr, GPR32:$swap),&lt;br /&gt;
   [(set i32:$dst, (atomic_swap GPR32:$ptr, GPR32:$swap))]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Non-Instruction Patterns&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// Shuffle patterns&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_shufflef32 v16f32:$src0, v16i32:$src1),&lt;br /&gt;
  (SHUFFLEI_32 v16f32:$src0, v16i32:$src1)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Splat patterns&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (splat i32:$src0)), (MOVE_VS_32 i32:$src0)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (splat f32:$src0)), (MOVE_VS_32 f32:$src0)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_vector_mixf32 v16f32:$src0, v16f32:$oldvalue),&lt;br /&gt;
          (MOVE_VV_M_32 v16f32:$src0, v16f32:$oldvalue)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- Patterns for load and store ----------------//&lt;br /&gt;
//---------------- scalar load and store ----------------//&lt;br /&gt;
// zextload bool -&amp;gt; zextload byte&lt;br /&gt;
def : Pat&amp;lt;(i32 (zextloadi1_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (zextloadi1_scratch ADDRri:$addr)), (L32BU_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- scalar extload-&amp;gt;zextload ----------------//&lt;br /&gt;
// Scalar load to 32-bit registers &lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi1_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi8_mem ADDRri:$addr)), (L32BU_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi16_mem ADDRri:$addr)), (L32SU_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(f32 (MemLoad ADDRri:$addr)), (L32W_Mainmem ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi1_scratch ADDRri:$addr)), (L32BU_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi8_scratch ADDRri:$addr)), (L32BU_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (extloadi16_scratch ADDRri:$addr)), (L32SU_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(f32 (ScratchpadLoad ADDRri:$addr)), (L32W_Scratchpad ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- scalar f32 load-&amp;gt; i32 load ----------------//&lt;br /&gt;
// Scalar store to 32-bit registers &lt;br /&gt;
def : Pat&amp;lt;(MemStore f32:$dstsrc, ADDRri:$addr), (S32W_Mainmem f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore f32:$dstsrc, ADDRri:$addr), (S32W_Scratchpad f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- vector load and store ----------------//&lt;br /&gt;
//---------------- intrinsics load and store ----------------//&lt;br /&gt;
//integer&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16i8 ADDRri:$addr)), (v16i32 (LV32BMainmem_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16i8_scratchpad ADDRri:$addr)), (v16i32 (LV32BScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16u8 ADDRri:$addr)), (v16i32 (LV32BUMainmem_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16u8_scratchpad ADDRri:$addr)), (v16i32 (LV32BUScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16i16 ADDRri:$addr)), (v16i32 (LV32SMainmem_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16i16_scratchpad ADDRri:$addr)), (v16i32 (LV32SScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16u16 ADDRri:$addr)), (v16i32 (LV32SUMainmem_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16u16_scratchpad ADDRri:$addr)), (v16i32 (LV32SUScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_block_loadv16i32_scratchpad ADDRri:$addr)), (v16i32 (LV32WScratchpad_U ADDRri:$addr))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_block_storev16i8 ADDRri:$addr, v16i32:$dstsrc), (SV32BMainmem_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_block_storev16i8_scratchpad ADDRri:$addr, v16i32:$dstsrc), (SV32BScratchpad_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_block_storev16i16 ADDRri:$addr, v16i32:$dstsrc), (SV32SMainmem_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_block_storev16i16_scratchpad ADDRri:$addr, v16i32:$dstsrc), (SV32SScratchpad_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_block_storev16i32_scratchpad ADDRri:$addr, v16i32:$dstsrc), (SV32WScratchpad_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//float&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (int_nuplus_block_loadv16f32_scratchpad ADDRri:$addr)), (LV32WScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (int_nuplus_block_loadv16f32_masked ADDRri:$addr)), (LV32WMainmem_M ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (int_nuplus_block_loadv16f32_scratchpad_masked ADDRri:$addr)), (LV32WScratchpad_M ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_block_storev16f32_scratchpad ADDRri:$addr, v16f32:$dstsrc), (SV32WScratchpad_U v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_block_storev16f32_masked ADDRri:$addr, v16f32:$dstsrc), (SV32WMainmem_M v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_block_storev16f32_scratchpad_masked ADDRri:$addr, v16f32:$dstsrc), (SV32WScratchpad_M v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Float gather/scatter&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_gather_loadf32_scratchpad V16ADDRri:$addr), (GLV32WScratchpad_U V16ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_gather_loadf32_scratchpad_masked V16ADDRri:$addr), (GLV32WScratchpad_M V16ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_scatter_storef32_scratchpad V16ADDRri:$addr, v16f32:$srcDest), (SSV32WScratchpad_U v16f32:$srcDest, V16ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(int_nuplus_scatter_storef32_scratchpad_masked V16ADDRri:$addr, v16f32:$srcDest), (SSV32WScratchpad_M v16f32:$srcDest, V16ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- vector anyextload -&amp;gt; sextload ----------------//&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (anyextloadv16i8_mem ADDRri:$addr)), (LV32BMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (anyextloadv16i8_scratch ADDRri:$addr)), (LV32BScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (anyextloadv16i16_mem ADDRri:$addr)), (LV32SMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (anyextloadv16i16_scratch ADDRri:$addr)), (LV32SScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- vector load/store -&amp;gt; sextload/truncstore ----------------//&lt;br /&gt;
def : Pat&amp;lt;(v16i8 (MemLoad ADDRri:$addr)),  (LV32BMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i8 (ScratchpadLoad ADDRri:$addr)),  (LV32BScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i16 (MemLoad ADDRri:$addr)), (LV32SMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i16 (ScratchpadLoad ADDRri:$addr)), (LV32SScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (ScratchpadLoad ADDRri:$addr)), (LV32WScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(MemStore v16i8:$dstsrc, ADDRri:$addr),  (SV32BMainmem_U v16i8:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(MemStore v16i16:$dstsrc, ADDRri:$addr), (SV32SMainmem_U v16i16:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore v16i8:$dstsrc, ADDRri:$addr),  (SV32BScratchpad_U v16i8:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore v16i16:$dstsrc, ADDRri:$addr), (SV32SScratchpad_U v16i16:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore v16i32:$dstsrc, ADDRri:$addr), (SV32WScratchpad_U v16i32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (MemLoad ADDRri:$addr)), (LV32WMainmem_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (ScratchpadLoad ADDRri:$addr)), (LV32WScratchpad_U ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(MemStore v16f32:$dstsrc, ADDRri:$addr), (SV32WMainmem_U v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore v16f32:$dstsrc, ADDRri:$addr), (SV32WScratchpad_U v16f32:$dstsrc, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Questi pattern servono per gestire i tipi di dato vettoriali di dim &amp;lt; 512 bits&lt;br /&gt;
// v16i8 &amp;lt;=&amp;gt; v16i32&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (bitconvert v16i8:$src)), (v16i32 (SEXT8_32VV_U v16i8:$src))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(MemStore (v16i8 (bitconvert v16i32:$src)), ADDRri:$addr), (SV32BMainmem_U v16i32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore (v16i8 (bitconvert v16i32:$src)), ADDRri:$addr), (SV32BScratchpad_U v16i32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
// v16i16 &amp;lt;=&amp;gt; v16i32&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (bitconvert v16i16:$src)), (v16i32 (SEXT16_32VV_U v16i16:$src))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(MemStore (v16i16 (bitconvert v16i32:$src)), ADDRri:$addr), (SV32SMainmem_U v16i32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(ScratchpadStore (v16i16 (bitconvert v16i32:$src)), ADDRri:$addr), (SV32SScratchpad_U v16i32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// v8f32 &amp;lt;=&amp;gt; v16f32&lt;br /&gt;
//def : Pat&amp;lt;(MemStore (v8f32 (extract_subvector v16f32:$src, (i32 0))), ADDRri:$addr), (SV32WMainmem_U v16f32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
//def : Pat&amp;lt;(ScratchpadStore (v8f32 (extract_subvector v16f32:$src, (i32 0))), ADDRri:$addr), (SV32WScratchpad_U v16f32:$src, ADDRri:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//---------------- Patterns for type conversions ----------------//&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Sign Extension Patterns sext_inreg -&amp;gt; sext&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (sext_inreg v16i32:$src, v16i8)), (v16i32 (SEXT8_32VV_U v16i32:$src))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (sext_inreg v16i32:$src, v16i16)), (v16i32 (SEXT16_32VV_U v16i32:$src))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// BITCAST patterns&lt;br /&gt;
def : Pat&amp;lt;(f32 (bitconvert (i32 GPR32:$src))), (f32 GPR32:$src)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (bitconvert (f32 GPR32:$src))), (i32 GPR32:$src)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16f32 (bitconvert (v16i32 VR512W:$src))), (v16f32 VR512W:$src)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (bitconvert (v16f32 VR512W:$src))), (v16i32 VR512W:$src)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// CLZ and CTZ Intrinsics&lt;br /&gt;
def : Pat&amp;lt;(i32 (int_nuplus_clzi32 i32:$src)),&lt;br /&gt;
(i32 (CLZSS_32 i32:$src))&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_clzv16i32 v16i32:$src)),&lt;br /&gt;
(v16i32 (CLZVV_U_32 v16i32:$src))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(i32 (int_nuplus_ctzi32 i32:$src)),&lt;br /&gt;
(i32 (CTZSS_32 i32:$src))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (int_nuplus_ctzv16i32 v16i32:$src)),&lt;br /&gt;
(v16i32 (CTZVV_U_32 v16i32:$src))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Integer division&lt;br /&gt;
// v16i32&lt;br /&gt;
def : Pat&amp;lt;(v16i32 (sdiv v16i32:$src1, v16i32:$src2)),&lt;br /&gt;
    (F32TOI32_VV_U (DIVFVVV_U_32 (I32TOF32_VV_U v16i32:$src1), (I32TOF32_VV_U v16i32:$src2)))&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Branch patterns&lt;br /&gt;
def : Pat&amp;lt;(brcond (i32 (setne i32:$lhs, 0)), bb:$addr), (BNEZ i32:$lhs, bb:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(brcond (i32 (seteq i32:$lhs, 0)), bb:$addr), (BEQZ i32:$lhs, bb:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(brcond i32:$lhs, bb:$addr), (BNEZ i32:$lhs, bb:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Call patterns&lt;br /&gt;
def : Pat&amp;lt;(call tglobaladdr:$addr), (JMPSR_OFF tglobaladdr:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(call texternalsym:$addr), (JMPSR_OFF texternalsym:$addr)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// GetLane patterns&lt;br /&gt;
def : Pat&amp;lt;(extractelt v16f32:$src0, i32:$src1),&lt;br /&gt;
          (GET_LANEI_32 v16f32:$src0, i32:$src1)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(extractelt v16f32:$src, simm9:$imm),&lt;br /&gt;
          (GET_LANEIimm v16f32:$src, imm:$imm)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// ISD Nodes Patterns&lt;br /&gt;
def : Pat&amp;lt;(i32 (leah tglobaladdr:$addr)), (LEAH tglobaladdr:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leal i32:$addrh, tglobaladdr:$addr)), (LEAL i32:$addrh, tglobaladdr:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leah tconstpool:$addr)), (LEAH tconstpool:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leal i32:$addrh, tconstpool:$addr)), (LEAL i32:$addrh, tconstpool:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leah tblockaddress:$addr)), (LEAH tblockaddress:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leal i32:$addrh, tblockaddress:$addr)), (LEAL i32:$addrh, tblockaddress:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leah tjumptable:$addr)), (LEAH tjumptable:$addr)&amp;gt;;&lt;br /&gt;
def : Pat&amp;lt;(i32 (leal i32:$addrh, tjumptable:$addr)), (LEAL i32:$addrh, tjumptable:$addr)&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusInstrInfo.td&amp;diff=2134</id>
		<title>NuPlusInstrInfo.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusInstrInfo.td&amp;diff=2134"/>
				<updated>2019-06-21T15:01:52Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusInstrInfo.td to NaplesPUInstrInfo.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUInstrInfo.td]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUInstrFormats.td&amp;diff=2132</id>
		<title>NaplesPUInstrFormats.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUInstrFormats.td&amp;diff=2132"/>
				<updated>2019-06-21T15:01:06Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
The NaplesPUInstrFormats.td contains the classes that describe the [[ISA|NaplesPU instruction formats]], support classes to facilitate the instructions definition and also the definition nodes which make the pattern recognition easier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NaplesPUInstrFormats.td - NaplesPU Instruction Formats ---*- tablegen -*-===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Instruction Pattern Stuff&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def simm16  : PatLeaf&amp;lt;(imm), [{ return isInt&amp;lt;16&amp;gt;(N-&amp;gt;getSExtValue()); }]&amp;gt;;&lt;br /&gt;
def simm9  : PatLeaf&amp;lt;(imm), [{ return isInt&amp;lt;9&amp;gt;(N-&amp;gt;getSExtValue()); }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Addressing modes as in SPARC&lt;br /&gt;
def ADDRri : ComplexPattern&amp;lt;iPTR, 2, &amp;quot;SelectADDRri&amp;quot;, [frameindex], []&amp;gt;;&lt;br /&gt;
def V16ADDRri : ComplexPattern&amp;lt;v16i32, 2, &amp;quot;SelectADDRri&amp;quot;, [], []&amp;gt;;&lt;br /&gt;
def V8ADDRri : ComplexPattern&amp;lt;v8i64, 2, &amp;quot;SelectADDRri&amp;quot;, [], []&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// NaplesPU profiles and nodes&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Transformation nodes&lt;br /&gt;
def LO32I : SDNodeXForm&amp;lt;imm, [{&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)N-&amp;gt;getAPIntValue().getLoBits(32).getZExtValue(), SDLoc(N), MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def HI32I : SDNodeXForm&amp;lt;imm, [{&lt;br /&gt;
  // Transformation function: shift the immediate value down into the low bits.&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)N-&amp;gt;getAPIntValue().getHiBits(32).getZExtValue(), SDLoc(N),  MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def LO32F : SDNodeXForm&amp;lt;fpimm, [{&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)(N-&amp;gt;getValueAPF().bitcastToAPInt().getLoBits(32).getZExtValue()), SDLoc(N), MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def HI32F : SDNodeXForm&amp;lt;fpimm, [{&lt;br /&gt;
  // Transformation function: shift the immediate value down into the low bits.&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)(N-&amp;gt;getValueAPF().bitcastToAPInt().getHiBits(32).getZExtValue()), SDLoc(N),  MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def DIV2 : SDNodeXForm&amp;lt;imm, [{&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)N-&amp;gt;getZExtValue() / 2, SDLoc(N), MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Moveil/moveih nodes definition, used for globaladdress lowering&lt;br /&gt;
def leah  : SDNode&amp;lt;&amp;quot;NaplesPUISD::LEAH&amp;quot;, SDTypeProfile&amp;lt;1, 1, []&amp;gt;&amp;gt;;&lt;br /&gt;
def leal  : SDNode&amp;lt;&amp;quot;NaplesPUISD::LEAL&amp;quot;, SDTypeProfile&amp;lt;1, 2, []&amp;gt;&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// A splat is a vector with the same value in all lanes. Used to handle operation&lt;br /&gt;
// with both vector and scalar operands.&lt;br /&gt;
def splat : SDNode&amp;lt;&amp;quot;NaplesPUISD::SPLAT&amp;quot;, SDTypeProfile&amp;lt;1, 1, [SDTCisEltOfVec&amp;lt;1, 0&amp;gt;]&amp;gt;&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def return : SDNode&amp;lt;&amp;quot;NaplesPUISD::RET_FLAG&amp;quot;, SDTypeProfile&amp;lt;0, 0, []&amp;gt;, &lt;br /&gt;
	[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def SDT_SPCall : SDTypeProfile&amp;lt;0, -1, [SDTCisVT&amp;lt;0, i32&amp;gt;]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def call : SDNode&amp;lt;&amp;quot;NaplesPUISD::CALL&amp;quot;, SDT_SPCall, &lt;br /&gt;
	[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//To mark the beginning and end of a call sequence&lt;br /&gt;
def SDT_SPCallSeqStart : SDCallSeqStart&amp;lt;[SDTCisVT&amp;lt;0, i32&amp;gt;, SDTCisVT&amp;lt;1, i32&amp;gt;]&amp;gt;;&lt;br /&gt;
 def SDT_SPCallSeqEnd : SDCallSeqEnd&amp;lt;[SDTCisVT&amp;lt;0, i32&amp;gt;, SDTCisVT&amp;lt;1, i32&amp;gt;]&amp;gt;;&lt;br /&gt;
 def callseq_start : SDNode&amp;lt;&amp;quot;ISD::CALLSEQ_START&amp;quot;, SDT_SPCallSeqStart,&lt;br /&gt;
                            [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]&amp;gt;;&lt;br /&gt;
 def callseq_end : SDNode&amp;lt;&amp;quot;ISD::CALLSEQ_END&amp;quot;, SDT_SPCallSeqEnd,&lt;br /&gt;
                            [SDNPHasChain, SDNPSideEffect,&lt;br /&gt;
                             SDNPOptInGlue, SDNPOutGlue]&amp;gt;; &lt;br /&gt;
//To handle the lack of conditional moves&lt;br /&gt;
def selcondresult : SDNode&amp;lt;&amp;quot;NaplesPUISD::SEL_COND_RESULT&amp;quot;, SDTypeProfile&amp;lt;1, 3, &lt;br /&gt;
							[SDTCisSameAs&amp;lt;0, 2&amp;gt;, SDTCisSameAs&amp;lt;0, 3&amp;gt;]&amp;gt;&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Operand Definitions&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// Used for the LEA_Sym, to detect the lea pseudo instruction&lt;br /&gt;
def symref : Operand&amp;lt;OtherVT&amp;gt; {}&lt;br /&gt;
&lt;br /&gt;
def SIMM16OP : Operand&amp;lt;i32&amp;gt; {&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeSimm16Value&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def SIMM9OP : Operand&amp;lt;i32&amp;gt; {&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeSimm9Value&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def MemAsmOperand : AsmOperandClass {&lt;br /&gt;
  let Name = &amp;quot;Mem&amp;quot;;&lt;br /&gt;
  let ParserMethod = &amp;quot;ParseMemoryOperand&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def MEMri : Operand&amp;lt;iPTR&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeMemoryOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeScalarMemoryOpValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand;&lt;br /&gt;
  let MIOperandInfo = (ops GPR32, i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def V16MEMri : Operand&amp;lt;v16i32&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeMemoryOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeVectorWMemoryOpValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand;&lt;br /&gt;
  let MIOperandInfo = (ops VR512W, i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def LEAri : Operand&amp;lt;iPTR&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeLEAValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass&lt;br /&gt;
  let MIOperandInfo = (ops GPR32, i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def ABSh : Operand&amp;lt;iPTR&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeABShValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass&lt;br /&gt;
  let MIOperandInfo = (ops i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def ABSl : Operand&amp;lt;iPTR&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeABSlValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass&lt;br /&gt;
  let MIOperandInfo = (ops i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def brtarget : Operand&amp;lt;OtherVT&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeBranchTargetOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeBranchTargetOpValue&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def calltarget : Operand&amp;lt;iPTR&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeBranchTargetOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeBranchTargetOpValue&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Pattern fragments&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Definition of anyextload used in the loading of vector types &amp;lt; 512 bits&lt;br /&gt;
def anyextload : PatFrag&amp;lt;(ops node:$ptr), (unindexedload node:$ptr), &lt;br /&gt;
    [{ return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getExtensionType() != ISD::NON_EXTLOAD;}]&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
//----------------------------------------------------------------------------// &lt;br /&gt;
//------------------------------ LOAD AND STORE ------------------------------// &lt;br /&gt;
//----------------------------------------------------------------------------// &lt;br /&gt;
&lt;br /&gt;
def MemStore : PatFrag&amp;lt;(ops node:$val, node:$ptr), (store node:$val, node:$ptr), [{&lt;br /&gt;
                            if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
                              return !cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;isTruncatingStore();&lt;br /&gt;
                            else&lt;br /&gt;
                              return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def MemLoad : PatFrag&amp;lt;(ops node:$ptr), (load node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getExtensionType() == ISD::NON_EXTLOAD;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def ScratchpadStore : PatFrag&amp;lt;(ops node:$val, node:$ptr), (store node:$val, node:$ptr), [{&lt;br /&gt;
                            if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
                              return !cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;isTruncatingStore();&lt;br /&gt;
                            else&lt;br /&gt;
                              return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def ScratchpadLoad : PatFrag&amp;lt;(ops node:$ptr), (load node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getExtensionType() == ISD::NON_EXTLOAD;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- EXTLOAD scalar ----------------// &lt;br /&gt;
def extloadi1_mem : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def extloadi1_scratch : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def extloadi8_mem : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def extloadi8_scratch : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def extloadi16_mem : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def extloadi16_scratch : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def extloadi32_mem : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def extloadi32_scratch : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- ZEXTLOAD scalar ----------------// &lt;br /&gt;
def zextloadi1_mem : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def zextloadi1_scratch : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadi8_mem : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def zextloadi8_scratch : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadi16_mem : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def zextloadi16_scratch : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadi32_mem : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def zextloadi32_scratch : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- ZEXTLOAD vector ----------------// &lt;br /&gt;
def zextloadv16i8_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv16i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadv16i16_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv16i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadv8i8_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv8i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadv8i16_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv8i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadv8i32_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv8i32_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;                  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//---------------- SEXTLOAD scalar ----------------// &lt;br /&gt;
def sextloadi1_mem : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def sextloadi1_scratch : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadi8_mem : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def sextloadi8_scratch : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadi16_mem : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def sextloadi16_scratch : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadi32_mem : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def sextloadi32_scratch : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
			&lt;br /&gt;
//---------------- SEXTLOAD vector ----------------// &lt;br /&gt;
def sextloadv16i8_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv16i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadv16i16_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv16i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadv8i8_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv8i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadv8i16_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv8i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadv8i32_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv8i32_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;                                    &lt;br /&gt;
&lt;br /&gt;
		 			&lt;br /&gt;
//---------------- ANYEXTLOAD vector ----------------// &lt;br /&gt;
def anyextloadv16i8_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr), &lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv16i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr), &lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def anyextloadv16i16_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv16i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def anyextloadv8i8_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv8i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;         &lt;br /&gt;
&lt;br /&gt;
def anyextloadv8i16_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv8i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def anyextloadv8i32_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv8i32_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		 &lt;br /&gt;
//---------------- TRUNCSTORE scalar ----------------// &lt;br /&gt;
def truncstorei1_mem : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def truncstorei1_scratch : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorei8_mem : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def truncstorei8_scratch : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorei16_mem : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def truncstorei16_scratch : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorei32_mem : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def truncstorei32_scratch : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- TRUNCSTORE vector ----------------// &lt;br /&gt;
def truncstorev16i8_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev16i8_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;   &lt;br /&gt;
&lt;br /&gt;
def truncstorev16i16_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev16i16_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorev8i8_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev8i8_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorev8i16_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev8i16_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorev8i32_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev8i32_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;                                                         &lt;br /&gt;
&lt;br /&gt;
			&lt;br /&gt;
// insertelt SDNode redefinition&lt;br /&gt;
def VecInsert : SDTypeProfile&amp;lt;1, 3, [    // vector insert&lt;br /&gt;
   SDTCisSameAs&amp;lt;0, 1&amp;gt;, SDTCisPtrTy&amp;lt;3&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def insert_elt  : SDNode&amp;lt;&amp;quot;ISD::INSERT_VECTOR_ELT&amp;quot;, VecInsert&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Describe NaplesPU Special Registers&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class SpReg&amp;lt;bits&amp;lt;6&amp;gt; reg&amp;gt; {&lt;br /&gt;
  bits&amp;lt;6&amp;gt; Register = reg;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def MaskReg : SpReg&amp;lt;59&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Describe NaplesPU scalar or vector instructions&lt;br /&gt;
//&lt;br /&gt;
//  Fmt   - 0 if a register is scalar, 1 if vector&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class Fmt&amp;lt;bit val&amp;gt; {&lt;br /&gt;
  bit Value = val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def Fmt_S : Fmt&amp;lt;0&amp;gt;;&lt;br /&gt;
def Fmt_V : Fmt&amp;lt;1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Describe NaplesPU instructions format here&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class InstNaplesPU&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern&amp;gt;&lt;br /&gt;
          : Instruction {&lt;br /&gt;
  field bits&amp;lt;32&amp;gt; Inst;&lt;br /&gt;
&lt;br /&gt;
  let Namespace = &amp;quot;NaplesPU&amp;quot;;&lt;br /&gt;
  let Size = 4;&lt;br /&gt;
&lt;br /&gt;
  dag OutOperandList = outs;&lt;br /&gt;
  dag InOperandList = ins;&lt;br /&gt;
  let AsmString   = asmstr;&lt;br /&gt;
  let Pattern = pattern;&lt;br /&gt;
&lt;br /&gt;
  //let DecoderNamespace = &amp;quot;NaplesPU&amp;quot;;&lt;br /&gt;
  field bits&amp;lt;32&amp;gt; SoftFail = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format R instruction class in NaplesPU : &amp;lt;00|opcode|rd|rs0|rs1|unused|l|fmt|m|&amp;gt;&lt;br /&gt;
// l: if 1, 64 bit mode&lt;br /&gt;
// fmt2: FMT value for rd register&lt;br /&gt;
// fmt1: FMT value for rs0 register&lt;br /&gt;
// fmt0: FMT value for rs1 register&lt;br /&gt;
// m: if 1, masked&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FR&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m&amp;gt;&lt;br /&gt;
   : InstNaplesPU&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dst;&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src0;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-30} = 0;&lt;br /&gt;
  let Inst{29-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-12} = src0;&lt;br /&gt;
  let Inst{5} = 0; //unused&lt;br /&gt;
  let Inst{4} = l;&lt;br /&gt;
  let Inst{3} = fmt2.Value;&lt;br /&gt;
  let Inst{2} = fmt1.Value;&lt;br /&gt;
  let Inst{1} = fmt0.Value;&lt;br /&gt;
  let Inst{0} = m;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m&amp;gt;&lt;br /&gt;
   : FR&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, m&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src1;&lt;br /&gt;
&lt;br /&gt;
  let Inst{11-6} = src1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m&amp;gt;&lt;br /&gt;
   : FR&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, m&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  let Inst{11-6} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Masked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, 1&amp;gt; {&lt;br /&gt;
  let Uses = [MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Unmasked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, 0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Masked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, Fmt_S, 1&amp;gt; {&lt;br /&gt;
  let Uses = [MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Unmasked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, Fmt_S, 0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Masked_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Masked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Unmasked_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Unmasked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Masked_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Masked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Unmasked_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Unmasked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format I instruction class in NaplesPU : &amp;lt;010|opcode|rd|rs|imm|fmt|m|&amp;gt;&lt;br /&gt;
// fmt1: FMT value for rd register&lt;br /&gt;
// fmt0: FMT value for rs register&lt;br /&gt;
// m: if 1 masked&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FI&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1, Fmt fmt0, bit m&amp;gt;&lt;br /&gt;
    : InstNaplesPU&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dst;&lt;br /&gt;
  bits &amp;lt;9&amp;gt; imm;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-29} = 0b010;&lt;br /&gt;
  let Inst{28-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{11-3} = imm;&lt;br /&gt;
  let Inst{2} = fmt1.Value;&lt;br /&gt;
  let Inst{1} = fmt0.Value;&lt;br /&gt;
  let Inst{0} = m;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FI_OneOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1, Fmt fmt0, bit m&amp;gt; : FI&amp;lt;outs, ins, asmstr, pattern, opcode, fmt1, fmt0, m&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src;&lt;br /&gt;
&lt;br /&gt;
  let Inst{17-12} = src;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FI_NoOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1&amp;gt; : FI&amp;lt;outs, ins, asmstr, pattern, opcode, fmt1, Fmt_S, 0&amp;gt; {&lt;br /&gt;
  let Inst{17-12} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FI_OneOp_Masked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1, Fmt fmt0&amp;gt; : FI_OneOp&amp;lt;outs, ins, asmstr, pattern, opcode, fmt1, fmt0, 1&amp;gt; {&lt;br /&gt;
  let Uses = [MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FI_OneOp_Unmasked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1, Fmt fmt0&amp;gt; : FI_OneOp&amp;lt;outs, ins, asmstr, pattern, opcode, fmt1, fmt0, 0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format MOVEI instruction class in NaplesPU : &amp;lt;01100|opcode|rd|imm|fmt|m|&amp;gt;&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FMOVEI&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode, Fmt fmt, bit m&amp;gt;&lt;br /&gt;
      : InstNaplesPU&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dst;&lt;br /&gt;
  bits &amp;lt;16&amp;gt; imm;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-27} = 0b01100;&lt;br /&gt;
  let Inst{26-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-2} = imm;&lt;br /&gt;
  let Inst{1} = fmt.Value;&lt;br /&gt;
  let Inst{0} = m;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format M instruction class in NaplesPU : &amp;lt;10|opcode|rd/rs|rptr|off|l|s|m|&amp;gt;&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FM&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, bit s, bit m&amp;gt;&lt;br /&gt;
    : InstNaplesPU&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dstsrc;&lt;br /&gt;
  bits &amp;lt;15&amp;gt; addr; //base address and offset encoded on the same 15 bits value (check encodeMemoryOpValue)&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-30} = 0b10;&lt;br /&gt;
  let Inst{29-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dstsrc;&lt;br /&gt;
  let Inst{17-12} = addr{5-0};&lt;br /&gt;
  let Inst{11-3} = addr{14-6};&lt;br /&gt;
  let Inst{2} = l;&lt;br /&gt;
  let Inst{1} = s;&lt;br /&gt;
  let Inst{0} = m;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, bit s&amp;gt;&lt;br /&gt;
   : FM&amp;lt;outs, ins, asmstr, pattern, opcode, l, s, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, bit s&amp;gt;&lt;br /&gt;
   : FM&amp;lt;outs, ins, asmstr, pattern, opcode, l, s, 1&amp;gt; {&lt;br /&gt;
  let Uses = [MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Mainmem&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l&amp;gt;&lt;br /&gt;
   : FM_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, l, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Scratchpad&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l&amp;gt;&lt;br /&gt;
   : FM_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, l, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Mainmem&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l&amp;gt;&lt;br /&gt;
   : FM_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, l, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Scratchpad&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l&amp;gt;&lt;br /&gt;
   : FM_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, l, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Mainmem_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Unmasked_Mainmem&amp;lt;outs, ins, asmstr, pattern, opcode, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Scratchpad_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Unmasked_Scratchpad&amp;lt;outs, ins, asmstr, pattern, opcode, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Mainmem_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Masked_Mainmem&amp;lt;outs, ins, asmstr, pattern, opcode, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Scratchpad_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Masked_Scratchpad&amp;lt;outs, ins, asmstr, pattern, opcode, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Mainmem_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Unmasked_Mainmem&amp;lt;outs, ins, asmstr, pattern, opcode, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Scratchpad_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Unmasked_Scratchpad&amp;lt;outs, ins, asmstr, pattern, opcode, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Mainmem_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Masked_Mainmem&amp;lt;outs, ins, asmstr, pattern, opcode, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Scratchpad_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Masked_Scratchpad&amp;lt;outs, ins, asmstr, pattern, opcode, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format J/BR instruction class in NaplesPU &lt;br /&gt;
// FJR: &amp;lt;0111|type(0/1)|opcode|rd|imm|&amp;gt;&lt;br /&gt;
// FJ:  &amp;lt;0111|type(0/1)|opcode|imm|&amp;gt;&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FJ_ALL&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode&amp;gt;&lt;br /&gt;
    : InstNaplesPU&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-28} = 0b0111;&lt;br /&gt;
  let Inst{26-24} = opcode;&lt;br /&gt;
  let isBranch = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FJR&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode&amp;gt;&lt;br /&gt;
    : FJ_ALL&amp;lt;outs, ins, asmstr, pattern, opcode&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; cond;&lt;br /&gt;
  bits &amp;lt;18&amp;gt; addr;&lt;br /&gt;
&lt;br /&gt;
  let Inst{27} = 0;&lt;br /&gt;
  let Inst{23-18} = cond;&lt;br /&gt;
  let Inst{17-0} = addr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FJ&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode&amp;gt;&lt;br /&gt;
    : FJ_ALL&amp;lt;outs, ins, asmstr, pattern, opcode&amp;gt; {&lt;br /&gt;
  bits &amp;lt;24&amp;gt; addr;&lt;br /&gt;
&lt;br /&gt;
  let Inst{27} = 1;&lt;br /&gt;
  let Inst{23-0} = addr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format C instruction class in NaplesPU &lt;br /&gt;
// FC:  &amp;lt;01101|opcode|rs0|rs1|unused|&amp;gt;&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FC&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode&amp;gt;&lt;br /&gt;
    : InstNaplesPU&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src0;&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src1;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-27} = 0b01101;&lt;br /&gt;
  let Inst{26-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = src0;&lt;br /&gt;
  let Inst{17-12} = src1;&lt;br /&gt;
  let Inst{11-0} = 0; //unused&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  A set of multiclasses is used to handle Vector/Scalar combinations&lt;br /&gt;
//   SS: Scalar = Op Scalar&lt;br /&gt;
//   VV: Vector = Op Vector&lt;br /&gt;
//   SI: Vector = Op Immediate&lt;br /&gt;
//  SSS: Scalar = Scalar Op Scalar&lt;br /&gt;
//  VVS: Vector = Vector Op Scalar&lt;br /&gt;
//  VVV: Vector = Vector Op Vector&lt;br /&gt;
//  SVV: Scalar = Vector Op Vector&lt;br /&gt;
//  SSI: Scalar = Vector Op Immediate&lt;br /&gt;
//  VVI: Scalar = Vector Op Immediate&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
multiclass FArithInt_TwoOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit integer&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src0, i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVS unmasked - 32 bit integer&lt;br /&gt;
  def VVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVV unmasked - 32 bit integer&lt;br /&gt;
  def VVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VVS masked - 32 bit integer&lt;br /&gt;
    def VVS_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_npu_vector_mixi32 (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // FR - VVV masked - 32 bit integer&lt;br /&gt;
    def VVV_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_npu_vector_mixi32 (OpNode v16i32:$src0, v16i32:$src1),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
  // FI - SSI&lt;br /&gt;
  def SSI : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src, (i32 simm9:$imm)))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - VVI unmasked&lt;br /&gt;
  def VVI_U : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - VVI masked&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    def VVI_M : FI_OneOp_Masked&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm, VR512W:$oldvalue),&lt;br /&gt;
    operator # &amp;quot;i.m $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_npu_vector_mixi32 (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))), v16i32:$oldvalue))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FArithInt_OneOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SS - 32 bit integer&lt;br /&gt;
  def SS_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VV unmasked - 32 bit integer&lt;br /&gt;
  def VV_U_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VV masked - 32 bit integer&lt;br /&gt;
    def VV_M_32 : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_npu_vector_mixi32 (OpNode v16i32:$src0),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// per la shift rotate&lt;br /&gt;
multiclass FSRInt_TwoOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit integer&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src0, i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVS unmasked - 32 bit integer&lt;br /&gt;
  def VVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVV unmasked - 32 bit integer&lt;br /&gt;
  def VVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VVS masked - 32 bit integer&lt;br /&gt;
    def VVS_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_npu_vector_mixi32 (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // FR - VVV masked - 32 bit integer&lt;br /&gt;
    def VVV_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_npu_vector_mixi32 (OpNode v16i32:$src0, v16i32:$src1),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
  // FI - SSI&lt;br /&gt;
  def SSI : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src, (i32 simm9:$imm)))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - VVI unmasked&lt;br /&gt;
  def VVI_U : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - VVI masked&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    def VVI_M : FI_OneOp_Masked&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm, VR512W:$oldvalue),&lt;br /&gt;
    operator # &amp;quot;i.m $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_npu_vector_mixi32 (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))), v16i32:$oldvalue))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FArithFloat_TwoOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit float&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set f32:$dst, (OpNode f32:$src0, f32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVS unmasked - 32 bit float&lt;br /&gt;
  def VVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (OpNode v16f32:$src0, (splat f32:$src1)))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVV unmasked - 32 bit float&lt;br /&gt;
  def VVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (OpNode v16f32:$src0, v16f32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VVS masked - 32 bit float&lt;br /&gt;
    def VVS_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),&lt;br /&gt;
    operator # &amp;quot;_f32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (int_npu_vector_mixf32 (OpNode v16f32:$src0, (splat f32:$src1)),&lt;br /&gt;
        v16f32:$oldvalue))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // FR - VVV masked - 32 bit float&lt;br /&gt;
    def VVV_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),&lt;br /&gt;
    operator # &amp;quot;_f32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (int_npu_vector_mixf32 (OpNode v16f32:$src0, v16f32:$src1),&lt;br /&gt;
        v16f32:$oldvalue))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FArithFloat_OneOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SS - 32 bit float&lt;br /&gt;
  def SS_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set f32:$dst, (OpNode f32:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VV unmasked - 32 bit float&lt;br /&gt;
  def VV_U_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (OpNode v16f32:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VV masked - 32 bit float&lt;br /&gt;
    def VV_M_32 : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_f32.m $dst, $src0&amp;quot;,&lt;br /&gt;
      [(set v16f32:$dst, (int_npu_vector_mixi32 (OpNode v16i32:$src0),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Condition codes defined in include/llvm/CodeGen/ISDOpcodes.h&lt;br /&gt;
// VS and VV comparisons are handled through intrinsics&lt;br /&gt;
multiclass FCompInt&amp;lt;string operator, CondCode condition,&lt;br /&gt;
  bits&amp;lt;6&amp;gt; opcode, Intrinsic vectorIntr32&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit integer&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (setcc i32:$src0, i32:$src1, condition))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - SVS unmasked - 32 bit integer&lt;br /&gt;
  def SVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16i32:$src0, (splat i32:$src1)))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - SVV unmasked - 32 bit integer&lt;br /&gt;
  def SVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - SSI&lt;br /&gt;
  def SSI : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (setcc i32:$src, simm9:$imm, condition))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - SVI unmasked&lt;br /&gt;
  def SVI : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16i32:$src, (splat simm9:$imm)))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FCompFloat&amp;lt;string operator, SDNode OpNode,&lt;br /&gt;
  bits&amp;lt;6&amp;gt; opcode, Intrinsic vectorIntr32&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit float&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode f32:$src0, f32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - SVS unmasked - 32 bit float&lt;br /&gt;
  def SVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16f32:$src0, (splat f32:$src1)))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - SVV unmasked - 32 bit float&lt;br /&gt;
  def SVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16f32:$src0, v16f32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FSext_32&amp;lt;string operator, ValueType vt,&lt;br /&gt;
  bits&amp;lt;6&amp;gt; opcode, ValueType vt_v&amp;gt; {&lt;br /&gt;
  // FR - SS&lt;br /&gt;
  def SS : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (sext_inreg i32:$src0, vt))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VV unmasked&lt;br /&gt;
  def VV_U : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (sext vt_v:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VV masked&lt;br /&gt;
    def VV_M : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_npu_vector_mixi32 (sext vt_v:$src0),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  A set of multiclasses used to handle Loads and Stores&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// Scalar LOAD&lt;br /&gt;
multiclass FMLoadScalar_32&amp;lt;string suffix, PatFrag op_mem, PatFrag op_scratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  def _Mainmem : FM_Unmasked_Mainmem&amp;lt;&lt;br /&gt;
    (outs GPR32:$dstsrc), &lt;br /&gt;
    (ins MEMri:$addr), &lt;br /&gt;
    &amp;quot;load32&amp;quot; # suffix # &amp;quot; $dstsrc, $addr&amp;quot;, &lt;br /&gt;
    [(set i32:$dstsrc, (i32 (op_mem ADDRri:$addr)))], &lt;br /&gt;
    opcode, &lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def _Scratchpad : FM_Unmasked_Scratchpad&amp;lt;&lt;br /&gt;
    (outs GPR32:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load32&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set i32:$dstsrc, (i32 (op_scratch ADDRri:$addr)))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Scalar STORE&lt;br /&gt;
multiclass FMStoreScalar_32&amp;lt;string suffix, PatFrag op_mem, PatFrag op_scratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  def _Mainmem : FM_Unmasked_Mainmem&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store32&amp;quot; # suffix # &amp;quot; $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_mem i32:$dstsrc, ADDRri:$addr)],&lt;br /&gt;
    opcode, &lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def _Scratchpad : FM_Unmasked_Scratchpad&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store32&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_scratch i32:$dstsrc, ADDRri:$addr)],&lt;br /&gt;
    opcode,&lt;br /&gt;
    0&amp;gt;{&lt;br /&gt;
        let hasSideEffects = 1;&lt;br /&gt;
        let mayStore = 1;&lt;br /&gt;
      }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Vector LOAD&lt;br /&gt;
multiclass FMLoadVector_32&amp;lt;string suffix, PatFrag op_Umem, PatFrag op_Uscratch, &lt;br /&gt;
                           Intrinsic op_Mmem, Intrinsic op_Mscratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  // main memory - unmasked - 32&lt;br /&gt;
  def Mainmem_U : FM_Unmasked_Mainmem_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load&amp;quot; # suffix # &amp;quot; $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Umem ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // scratchpad memory - unmasked - 32&lt;br /&gt;
  def Scratchpad_U : FM_Unmasked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Uscratch ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // main memory - masked - 32&lt;br /&gt;
  def Mainmem_M : FM_Masked_Mainmem_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load&amp;quot; # suffix # &amp;quot;.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Mmem ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // scratchpad memory - masked - 32&lt;br /&gt;
  def Scratchpad_M : FM_Masked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load&amp;quot; # suffix # &amp;quot;_scratchpad.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Mscratch ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Vector GATHER&lt;br /&gt;
multiclass FMGather_32&amp;lt;string suffix, Intrinsic op_Uscratch, &lt;br /&gt;
                           Intrinsic op_Mscratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  &lt;br /&gt;
  // scratchpad memory - unmasked - 32&lt;br /&gt;
  def Scratchpad_U : FM_Unmasked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins V16MEMri:$addr),&lt;br /&gt;
    &amp;quot;loadg&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Uscratch V16ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
  // scratchpad memory - masked - 32&lt;br /&gt;
  def Scratchpad_M : FM_Masked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins V16MEMri:$addr),&lt;br /&gt;
    &amp;quot;loadg&amp;quot; # suffix # &amp;quot;_scratchpad.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Mscratch V16ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Vector STORE&lt;br /&gt;
multiclass FMStoreVector_32&amp;lt;string suffix, PatFrag op_Umem, PatFrag op_Uscratch, &lt;br /&gt;
                           Intrinsic op_Mmem, Intrinsic op_Mscratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  // main memory - unmasked - 32&lt;br /&gt;
  def Mainmem_U : FM_Unmasked_Mainmem_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store&amp;quot; # suffix # &amp;quot; $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Umem v16i32:$dstsrc, ADDRri:$addr)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
  // scratchpad memory - unmasked - 32&lt;br /&gt;
  def Scratchpad_U : FM_Unmasked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Uscratch v16i32:$dstsrc, ADDRri:$addr)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
  // main memory - masked - 32&lt;br /&gt;
  def Mainmem_M : FM_Masked_Mainmem_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store&amp;quot; # suffix # &amp;quot;.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Mmem ADDRri:$addr, v16i32:$dstsrc)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
  // scratchpad memory - masked - 32&lt;br /&gt;
  def Scratchpad_M : FM_Masked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store&amp;quot; # suffix # &amp;quot;_scratchpad.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Mscratch ADDRri:$addr, v16i32:$dstsrc)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Vector SCATTER&lt;br /&gt;
multiclass FMScatter_32&amp;lt;string suffix, Intrinsic op_Uscratch, &lt;br /&gt;
                           Intrinsic op_Mscratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  // scratchpad memory - unmasked - 32&lt;br /&gt;
  def Scratchpad_U : FM_Unmasked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, V16MEMri:$addr),&lt;br /&gt;
    &amp;quot;stores&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Uscratch V16ADDRri:$addr, v16i32:$dstsrc)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // scratchpad memory - masked - 32&lt;br /&gt;
  def Scratchpad_M : FM_Masked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, V16MEMri:$addr),&lt;br /&gt;
    &amp;quot;stores&amp;quot; # suffix # &amp;quot;_scratchpad.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Mscratch V16ADDRri:$addr, v16i32:$dstsrc)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  A set of multiclasses is used to handle Vector/Scalar &lt;br /&gt;
//  Masked/Unmasked combinations&lt;br /&gt;
//  MOVEI operations&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
multiclass FMOVEI_ALL&amp;lt;string operator, bits&amp;lt;3&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // SI&lt;br /&gt;
  def SI : FMOVEI&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins SIMM16OP:$imm),&lt;br /&gt;
    operator # &amp;quot; $dst, $imm&amp;quot;,&lt;br /&gt;
    [],//[(set i32:$dst, simm16:$imm)],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // VI unmasked&lt;br /&gt;
  def VI_U : FMOVEI&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins SIMM16OP:$imm),&lt;br /&gt;
    operator # &amp;quot; $dst, $imm&amp;quot;,&lt;br /&gt;
    [],//[(set v16i32:$dst, (splat simm16:$imm))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
 let Constraints = &amp;quot;$dst = $oldvalue&amp;quot;, Uses = [MR_REG] in {&lt;br /&gt;
    // VI masked&lt;br /&gt;
    def VI_M : FMOVEI&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins SIMM16OP:$imm, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;.m $dst, $imm&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_npu_vector_mixi32 (splat simm16:$imm), v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      1&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Instruction class used to read/write special register through intrinics&lt;br /&gt;
// All these instructions are implemented using a move instruction&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
let DecoderNamespace = &amp;quot;Read_SPR&amp;quot; in {&lt;br /&gt;
  class READ_SPR&amp;lt;SpReg reg, string operator, Intrinsic read_intr&amp;gt; :&lt;br /&gt;
                FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
                  (outs GPR32:$dst),&lt;br /&gt;
                  (ins),&lt;br /&gt;
                  operator # &amp;quot; $dst&amp;quot;,&lt;br /&gt;
                  [(set i32:$dst, (read_intr))],&lt;br /&gt;
                  32,&lt;br /&gt;
                  Fmt_S,&lt;br /&gt;
                  Fmt_S&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
    let Inst{29-24} = 32; // opcode: move&lt;br /&gt;
    let Inst{23-18} = dst;&lt;br /&gt;
    let Inst{17-12} = reg.Register;&lt;br /&gt;
    let Inst{11-6} = 0;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
let DecoderNamespace = &amp;quot;Write_SPR&amp;quot; in {&lt;br /&gt;
  class WRITE_SPR&amp;lt;SpReg reg, string operator, Intrinsic read_intr&amp;gt; :&lt;br /&gt;
                FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
                  (outs),&lt;br /&gt;
                  (ins GPR32:$src),&lt;br /&gt;
                  operator # &amp;quot; $src&amp;quot;,&lt;br /&gt;
                  [(read_intr i32:$src)],&lt;br /&gt;
                  32,&lt;br /&gt;
                  Fmt_S,&lt;br /&gt;
                  Fmt_S&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    bits&amp;lt;6&amp;gt; src;&lt;br /&gt;
&lt;br /&gt;
    let Inst{29-24} = 32; // opcode: move&lt;br /&gt;
    let Inst{23-18} = reg.Register;&lt;br /&gt;
    let Inst{17-12} = src;&lt;br /&gt;
    let Inst{11-6} = 0;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Pseudo-instructions for alternate assembly syntax (never used by codegen).&lt;br /&gt;
//  These are aliases that require C++ handling to convert to the target&lt;br /&gt;
//  instruction, while InstAliases can be handled directly by tblgen.&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
class AsmPseudoInst&amp;lt;dag outs, dag ins, string asm&amp;gt;&lt;br /&gt;
  : InstNaplesPU&amp;lt;outs, ins, asm, []&amp;gt; {&lt;br /&gt;
  let isPseudo = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class Pseudo&amp;lt;dag outs, dag ins, list&amp;lt;dag&amp;gt; pattern&amp;gt;&lt;br /&gt;
  : InstNaplesPU&amp;lt;outs, ins, &amp;quot;Pseudo&amp;quot;, pattern&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  let isCodeGenOnly = 1;&lt;br /&gt;
  let isPseudo = 1;&lt;br /&gt;
  let Inst{31-0} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass AtomicBinary&amp;lt;SDNode OpNode&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  def R : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$ptr, GPR32:$amt),&lt;br /&gt;
    [(set i32:$dst, (OpNode GPR32:$ptr, GPR32:$amt))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def I : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$ptr, SIMM9OP:$amt),&lt;br /&gt;
    [(set i32:$dst, (OpNode GPR32:$ptr, simm9:$amt))]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUISelDAGToDAG.cpp&amp;diff=2131</id>
		<title>NaplesPUISelDAGToDAG.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUISelDAGToDAG.cpp&amp;diff=2131"/>
				<updated>2019-06-21T14:59:54Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The NaplesPUDAGToDAGISel class is used to transform target independent LLVM DAG nodes into platform dependent nodes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NaplesPUISelDAGToDAG.cpp - A dag to dag inst selector for NaplesPU ------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This pass transforms target independent LLVM DAG nodes into platform&lt;br /&gt;
// dependent nodes that map, for the most part, directly to target instructions.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#define DEBUG_TYPE &amp;quot;naplespu-isel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NaplesPUTargetMachine.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/SelectionDAGISel.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/IR/Intrinsics.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Compiler.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/ErrorHandling.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
namespace {&lt;br /&gt;
class NaplesPUDAGToDAGISel : public SelectionDAGISel {&lt;br /&gt;
public:&lt;br /&gt;
  explicit NaplesPUDAGToDAGISel(NaplesPUTargetMachine &amp;amp;tm) : SelectionDAGISel(tm) {}&lt;br /&gt;
&lt;br /&gt;
  void Select(SDNode *N) override;&lt;br /&gt;
&lt;br /&gt;
  bool SelectInlineAsmMemoryOperand(const SDValue &amp;amp;Op, unsigned ConstraintCode,&lt;br /&gt;
                                    std::vector&amp;lt;SDValue&amp;gt; &amp;amp;OutOps) override;  &lt;br /&gt;
&lt;br /&gt;
  bool SelectADDRri(SDValue N, SDValue &amp;amp;Base, SDValue &amp;amp;Offset);&lt;br /&gt;
&lt;br /&gt;
  StringRef getPassName() const override {&lt;br /&gt;
    return &amp;quot;NaplesPU DAG-&amp;gt;DAG Pattern Instruction Selection&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NaplesPUGenDAGISel.inc&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
} // end anonymous namespace&lt;br /&gt;
&lt;br /&gt;
bool NaplesPUDAGToDAGISel::SelectADDRri(SDValue Addr, SDValue &amp;amp;Base,&lt;br /&gt;
                                     SDValue &amp;amp;Offset) {&lt;br /&gt;
&lt;br /&gt;
  if (FrameIndexSDNode *FIN = dyn_cast&amp;lt;FrameIndexSDNode&amp;gt;(Addr)) {&lt;br /&gt;
    Base = CurDAG-&amp;gt;getTargetFrameIndex(FIN-&amp;gt;getIndex(), MVT::i32);&lt;br /&gt;
    Offset = CurDAG-&amp;gt;getTargetConstant(0, SDLoc(Addr), MVT::i32);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||&lt;br /&gt;
      Addr.getOpcode() == ISD::TargetGlobalAddress)&lt;br /&gt;
    return false; // direct calls.&lt;br /&gt;
&lt;br /&gt;
  if (Addr.getOpcode() == ISD::ADD) {&lt;br /&gt;
        if (ConstantSDNode *CN = dyn_cast&amp;lt;ConstantSDNode&amp;gt;(Addr.getOperand(1))) {&lt;br /&gt;
      if (isInt&amp;lt;9&amp;gt;(CN-&amp;gt;getSExtValue())) {&lt;br /&gt;
        if (FrameIndexSDNode *FIN =&lt;br /&gt;
                dyn_cast&amp;lt;FrameIndexSDNode&amp;gt;(Addr.getOperand(0))) {&lt;br /&gt;
          Base = CurDAG-&amp;gt;getTargetFrameIndex(FIN-&amp;gt;getIndex(), MVT::i32);&lt;br /&gt;
        } else {&lt;br /&gt;
          Base = Addr.getOperand(0);&lt;br /&gt;
        }&lt;br /&gt;
        Offset = CurDAG-&amp;gt;getTargetConstant(CN-&amp;gt;getZExtValue(), SDLoc(Addr),&lt;br /&gt;
                                           MVT::i32);&lt;br /&gt;
        return true;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  Base = Addr;&lt;br /&gt;
  Offset = CurDAG-&amp;gt;getTargetConstant(0, SDLoc(Addr), MVT::i32);&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NaplesPUDAGToDAGISel::Select(SDNode *N) {&lt;br /&gt;
 SDLoc DL(N);&lt;br /&gt;
 if (N-&amp;gt;isMachineOpcode())&lt;br /&gt;
   return; // Already selected.&lt;br /&gt;
&lt;br /&gt;
  SelectCode(N);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool NaplesPUDAGToDAGISel::SelectInlineAsmMemoryOperand(&lt;br /&gt;
    const SDValue &amp;amp;Op, unsigned ConstraintCode, std::vector&amp;lt;SDValue&amp;gt; &amp;amp;OutOps) {&lt;br /&gt;
  SDValue Op0, Op1;&lt;br /&gt;
  switch (ConstraintCode) {&lt;br /&gt;
  default:&lt;br /&gt;
    return true;&lt;br /&gt;
&lt;br /&gt;
  case 'm': // memory&lt;br /&gt;
    SelectADDRri(Op, Op0, Op1);&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  OutOps.push_back(Op0);&lt;br /&gt;
  OutOps.push_back(Op1);&lt;br /&gt;
  return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
FunctionPass *llvm::createNaplesPUISelDag(NaplesPUTargetMachine &amp;amp;TM) {&lt;br /&gt;
  return new NaplesPUDAGToDAGISel(TM);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUCallingConv.td&amp;diff=2130</id>
		<title>NaplesPUCallingConv.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUCallingConv.td&amp;diff=2130"/>
				<updated>2019-06-21T14:58:39Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
This file describes the conventions to use when a function is called, such as how to pass the arguments and how to return the function results.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NaplesPUCallingConv.td - Calling Conventions NaplesPU ----*- tablegen -*-===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This describes the calling conventions for the NaplesPU architectures.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def CC_NaplesPU32 : CallingConv&amp;lt;[&lt;br /&gt;
&lt;br /&gt;
  // i1, i8 and i16 integers are promoted to i32 by the caller.&lt;br /&gt;
  CCIfType&amp;lt;[i1, i8, i16], CCPromoteToType&amp;lt;i32&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  CCIfType&amp;lt;[v16i8, v16i16], CCPromoteToType&amp;lt;v16i32&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[v8i8, v8i16, v8i32], CCPromoteToType&amp;lt;v8i64&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  // i32 f32 arguments get passed in integer registers if there is space.&lt;br /&gt;
  CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[i32, f32], CCAssignToReg&amp;lt;[S0, S1, S2, S3, S4, S5, S6, S7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
    // Vector arguments can be passed in their own registers, as above&lt;br /&gt;
  CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[v16i32, v16f32], CCAssignToReg&amp;lt;[V0, V1, V2, V3, V4, V5, V6, V7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  // Stick remaining registers onto stack, aligned by size&lt;br /&gt;
  CCIfType&amp;lt;[i32, f32], CCAssignToStack&amp;lt;4, 4&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[v16i32, v16f32], CCAssignToStack&amp;lt;64, 64&amp;gt;&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def RetCC_NaplesPU32 : CallingConv&amp;lt;[&lt;br /&gt;
  CCIfType&amp;lt;[i1, i8, i16], CCPromoteToType&amp;lt;i32&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  CCIfType&amp;lt;[i32, f32], CCAssignToReg&amp;lt;[S0, S1, S2, S3, S4, S5]&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  CCIfType&amp;lt;[v16i8, v16i16], CCPromoteToType&amp;lt;v16i32&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  CCIfType&amp;lt;[v16i32, v16f32], CCAssignToReg&amp;lt;[V0, V1, V2, V3, V4, V5]&amp;gt;&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Callee only needs to save the callee-save registers that are used in the body of its subroutine.&lt;br /&gt;
def NaplesPUCSR : CalleeSavedRegs&amp;lt;(add (sequence &amp;quot;S%u&amp;quot;, 50, 57), MR_REG, FP_REG, RA_REG,&lt;br /&gt;
                               (sequence &amp;quot;V%u&amp;quot;, 56, 63))&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPURegisterInfo.td&amp;diff=2129</id>
		<title>NaplesPURegisterInfo.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPURegisterInfo.td&amp;diff=2129"/>
				<updated>2019-06-21T14:56:45Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
The NaplesPURegisterInfo.td is used to define the NaplesPU hw registers and the NaplesPU register classes. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line='line'&amp;gt;&lt;br /&gt;
//===-- NaplesPURegisterInfo.td - NaplesPU Register defs ---------*- tablegen -*-===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Declarations that describe the NaplesPU register file&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
let Namespace = &amp;quot;NaplesPU&amp;quot; in {&lt;br /&gt;
def sub_even : SubRegIndex&amp;lt;32&amp;gt;;&lt;br /&gt;
def sub_odd  : SubRegIndex&amp;lt;32, 32&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class NaplesPUReg&amp;lt;bits&amp;lt;16&amp;gt; Enc, string n&amp;gt; : Register&amp;lt;n&amp;gt; {&lt;br /&gt;
  let HWEncoding = Enc;&lt;br /&gt;
  let Namespace = &amp;quot;NaplesPU&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class NaplesPURegWithSubRegs&amp;lt;bits&amp;lt;16&amp;gt; Enc, string n, list&amp;lt;Register&amp;gt; subregs&amp;gt;&lt;br /&gt;
  : RegisterWithSubRegs&amp;lt;n, subregs&amp;gt; {&lt;br /&gt;
  let HWEncoding = Enc;&lt;br /&gt;
  let Namespace = &amp;quot;NaplesPU&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// NaplesPU 32-bit registers&lt;br /&gt;
class NaplesPUGPRReg&amp;lt;bits&amp;lt;16&amp;gt; Enc, string n&amp;gt; : NaplesPUReg&amp;lt;Enc, n&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Registers&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // General Purpose scalar registers&lt;br /&gt;
  foreach i = 0-57 in {&lt;br /&gt;
    def S#i : NaplesPUGPRReg&amp;lt;i, &amp;quot;s&amp;quot;#i&amp;gt;, DwarfRegNum&amp;lt;[i]&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //trap register&lt;br /&gt;
  def TR_REG : NaplesPUGPRReg&amp;lt;58, &amp;quot;tr&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[58]&amp;gt;;&lt;br /&gt;
  //mask register&lt;br /&gt;
  def MR_REG : NaplesPUGPRReg&amp;lt;59, &amp;quot;rm&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[59]&amp;gt;;&lt;br /&gt;
  //frame pointer&lt;br /&gt;
  def FP_REG : NaplesPUGPRReg&amp;lt;60, &amp;quot;fp&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[60]&amp;gt;;&lt;br /&gt;
  //stack pointer&lt;br /&gt;
  def SP_REG : NaplesPUGPRReg&amp;lt;61, &amp;quot;sp&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[61]&amp;gt;;&lt;br /&gt;
  //return address&lt;br /&gt;
  def RA_REG : NaplesPUGPRReg&amp;lt;62, &amp;quot;ra&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[62]&amp;gt;;&lt;br /&gt;
  //PC&lt;br /&gt;
  def PC_REG : NaplesPUGPRReg&amp;lt;63, &amp;quot;pc&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[63]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // General Purpose vectorial registers&lt;br /&gt;
  foreach i = 0-63 in {&lt;br /&gt;
    def V#i : NaplesPUGPRReg&amp;lt;i, &amp;quot;v&amp;quot;#i&amp;gt;, DwarfRegNum&amp;lt;[!add(i, 64)]&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Register Classes&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// This register class should not be used to hold i64/f64 values, use the GPR64&lt;br /&gt;
// register class for that. The i64/f64 type is included here to allow i64/f64&lt;br /&gt;
// patterns using the instructions.&lt;br /&gt;
def GPR32 : RegisterClass&amp;lt;&amp;quot;NaplesPU&amp;quot;, [i32, f32], 32, (add (sequence &amp;quot;S%u&amp;quot;, 0, 57),&lt;br /&gt;
  TR_REG, MR_REG, FP_REG, SP_REG, RA_REG, PC_REG)&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def VR512W : RegisterClass&amp;lt;&amp;quot;NaplesPU&amp;quot;, [v16i32, v16f32, v16i8, v16i16], 512, (sequence &amp;quot;V%u&amp;quot;, 0, 63)&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU.td&amp;diff=2128</id>
		<title>NaplesPU.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU.td&amp;diff=2128"/>
				<updated>2019-06-21T14:55:37Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
The NaplesPU.td file contains the definition of the Target class '''NaplesPU''' (defined in &amp;quot;compiler/include/llvm/Target/Target.td&amp;quot;). The file also contains the definition of the '''NaplesPUInstrInfo''', '''NaplesPUAsmParser''' and '''NaplesPUAsmWriter''' required by the '''Target''' class. In addition, we avoid using instruction itineraries for scheduling. Itineraries are details reservation tables for each instruction class. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line='line'&amp;gt;&lt;br /&gt;
//===-- NaplesPU.td - Describe the NaplesPU Target Machine -------*- tablegen -*-===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//MCCodeEmitter/===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Target-independent interfaces which we are implementing&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
include &amp;quot;llvm/Target/Target.td&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Register File, Calling Conv, Instruction Descriptions&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
include &amp;quot;NaplesPURegisterInfo.td&amp;quot;&lt;br /&gt;
include &amp;quot;NaplesPUCallingConv.td&amp;quot;&lt;br /&gt;
include &amp;quot;NaplesPUInstrInfo.td&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def NaplesPUInstrInfo : InstrInfo;&lt;br /&gt;
&lt;br /&gt;
def NaplesPUAsmParser : AsmParser {&lt;br /&gt;
  bit ShouldEmitMatchRegisterName = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Declare the target which we are implementing&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def NaplesPUAsmWriter : AsmWriter {&lt;br /&gt;
  string AsmWriterClassName  = &amp;quot;InstPrinter&amp;quot;;&lt;br /&gt;
  bit isMCAsmWriter = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def : Processor&amp;lt;&amp;quot;naplespu&amp;quot;, NoItineraries, []&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def NaplesPU : Target {&lt;br /&gt;
  // Pull in Instruction Info:&lt;br /&gt;
  let InstructionSet = NaplesPUInstrInfo;&lt;br /&gt;
  let AssemblyParsers  = [NaplesPUAsmParser];&lt;br /&gt;
  let AssemblyWriters = [NaplesPUAsmWriter];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUMCCodeEmitter.cpp&amp;diff=2125</id>
		<title>NaplesPUMCCodeEmitter.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUMCCodeEmitter.cpp&amp;diff=2125"/>
				<updated>2019-06-21T14:51:21Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusMCCodeEmitter.cpp to NaplesPUMCCodeEmitter.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NuPlusMCCodeEmitter class transforms MCInst objects into binary code representation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusMCCodeEmitter.cpp - Convert NuPlus code to machine code -------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This file implements the NuPlusMCCodeEmitter class.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NuPlusFixupKinds.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NuPlusMCTargetDesc.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/ADT/Statistic.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCCodeEmitter.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCContext.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCExpr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCFixup.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInst.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCRegisterInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSubtargetInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSymbol.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#define DEBUG_TYPE &amp;quot;mccodeemitter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STATISTIC(MCNumEmitted, &amp;quot;Number of MC instructions emitted&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
namespace {&lt;br /&gt;
class NuPlusMCCodeEmitter : public MCCodeEmitter {&lt;br /&gt;
  NuPlusMCCodeEmitter(const NuPlusMCCodeEmitter &amp;amp;) = delete;&lt;br /&gt;
  void operator=(const NuPlusMCCodeEmitter &amp;amp;) = delete;&lt;br /&gt;
  MCContext &amp;amp;Ctx;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
  NuPlusMCCodeEmitter(const MCInstrInfo &amp;amp;mcii, MCContext &amp;amp;ctx): Ctx(ctx) {}&lt;br /&gt;
&lt;br /&gt;
  // getBinaryCodeForInstr - TableGen'erated function for getting the&lt;br /&gt;
  // binary encoding for an instruction.&lt;br /&gt;
  uint64_t getBinaryCodeForInstr(const MCInst &amp;amp;MI,&lt;br /&gt;
                                 SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                 const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
&lt;br /&gt;
  /// getMachineOpValue - Return binary encoding of operand. If the machine&lt;br /&gt;
  /// operand requires relocation, record the relocation and return zero.&lt;br /&gt;
  unsigned getMachineOpValue(const MCInst &amp;amp;MI, const MCOperand &amp;amp;MO,&lt;br /&gt;
                             SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                             const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
&lt;br /&gt;
  void encodeInstruction(const MCInst &amp;amp;MI, raw_ostream &amp;amp;OS,&lt;br /&gt;
                         SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                         const MCSubtargetInfo &amp;amp;STI) const override;&lt;br /&gt;
&lt;br /&gt;
  unsigned encodeMemoryOpValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                               SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                               const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
&lt;br /&gt;
  unsigned encodeLEAValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                          SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                          const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
&lt;br /&gt;
  unsigned encodeABShValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                          SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                          const MCSubtargetInfo &amp;amp;STI) const; &lt;br /&gt;
&lt;br /&gt;
  unsigned encodeABSlValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                          SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                          const MCSubtargetInfo &amp;amp;STI) const;                        &lt;br /&gt;
&lt;br /&gt;
  unsigned encodeBranchTargetOpValue(const MCInst &amp;amp;MI, unsigned OpNo,&lt;br /&gt;
                                     SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                     const MCSubtargetInfo &amp;amp;STI) const;&lt;br /&gt;
  &lt;br /&gt;
  // Emit one byte through output stream (from MCBlazeMCCodeEmitter)&lt;br /&gt;
  void EmitByte(unsigned char C, raw_ostream &amp;amp;OS) const { OS &amp;lt;&amp;lt; (char)C; }&lt;br /&gt;
&lt;br /&gt;
  void EmitLEConstant(uint64_t Val, unsigned Size, raw_ostream &amp;amp;OS) const {&lt;br /&gt;
    assert(Size &amp;lt;= 8 &amp;amp;&amp;amp; &amp;quot;size too big in emit constant&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (unsigned i = 0; i != Size; ++i) {&lt;br /&gt;
      EmitByte(Val &amp;amp; 255, OS);&lt;br /&gt;
      Val &amp;gt;&amp;gt;= 8;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
} // end anonymous namespace&lt;br /&gt;
&lt;br /&gt;
MCCodeEmitter *llvm::createNuPlusMCCodeEmitter(const MCInstrInfo &amp;amp;MCII,&lt;br /&gt;
                                              const MCRegisterInfo &amp;amp;MRI,&lt;br /&gt;
                                              MCContext &amp;amp;Ctx) {&lt;br /&gt;
  return new NuPlusMCCodeEmitter(MCII, Ctx);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return binary encoding of operand.&lt;br /&gt;
unsigned NuPlusMCCodeEmitter::&lt;br /&gt;
getMachineOpValue(const MCInst &amp;amp;MI, const MCOperand &amp;amp;MO,&lt;br /&gt;
                  SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                  const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
&lt;br /&gt;
  if (MO.isReg())&lt;br /&gt;
    return Ctx.getRegisterInfo()-&amp;gt;getEncodingValue(MO.getReg());&lt;br /&gt;
&lt;br /&gt;
  if (MO.isImm())&lt;br /&gt;
    return static_cast&amp;lt;unsigned&amp;gt;(MO.getImm());&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusMCCodeEmitter::encodeInstruction(const MCInst &amp;amp;MI, raw_ostream &amp;amp;OS,&lt;br /&gt;
                                           SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                           const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);&lt;br /&gt;
  EmitLEConstant(Bits, 4, OS);&lt;br /&gt;
&lt;br /&gt;
  ++MCNumEmitted;  // Keep track of the # of mi's emitted.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned NuPlusMCCodeEmitter::encodeABShValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                                            SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                            const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  // with LEAH the second operand is expected to be the global address&lt;br /&gt;
  //MCOperand address = MI.getOperand(1);&lt;br /&gt;
  // the third operand is the label used in the asm&lt;br /&gt;
  //MCOperand address_asm = MI.getOperand(2);&lt;br /&gt;
&lt;br /&gt;
  if (MI.getOperand(1).isExpr()) {&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0, MI.getOperand(1).getExpr(),&lt;br /&gt;
        MCFixupKind(NuPlus::fixup_NuPlus_Absh)));&lt;br /&gt;
  } else if ( MI.getOperand(2).isExpr()) {&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0,  MI.getOperand(2).getExpr(),&lt;br /&gt;
        MCFixupKind(NuPlus::fixup_NuPlus_Absh)));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned NuPlusMCCodeEmitter::encodeABSlValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                                            SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                            const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  // with LEAH the third operand is expected to be the global address&lt;br /&gt;
  //MCOperand address = MI.getOperand(2);&lt;br /&gt;
  // the fourth operand is the label used in the asm&lt;br /&gt;
  //MCOperand address_asm = MI.getOperand(3);&lt;br /&gt;
&lt;br /&gt;
  if (MI.getOperand(2).isExpr()) {&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0, MI.getOperand(2).getExpr(),&lt;br /&gt;
        MCFixupKind(NuPlus::fixup_NuPlus_Absl)));&lt;br /&gt;
  } else if (MI.getOperand(3).isExpr()) {&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0, MI.getOperand(3).getExpr(),&lt;br /&gt;
        MCFixupKind(NuPlus::fixup_NuPlus_Absl)));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned NuPlusMCCodeEmitter::encodeLEAValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                                            SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                            const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  MCOperand baseReg = MI.getOperand(1);&lt;br /&gt;
  MCOperand offsetOp = MI.getOperand(2);&lt;br /&gt;
&lt;br /&gt;
  assert(baseReg.isReg() &amp;amp;&amp;amp; &amp;quot;First operand of LEA op is not register.&amp;quot;);&lt;br /&gt;
  unsigned encoding = Ctx.getRegisterInfo()-&amp;gt;getEncodingValue(baseReg.getReg())&amp;lt;&amp;lt;10;&lt;br /&gt;
  if (offsetOp.isExpr()) {&lt;br /&gt;
    // Load with a label. This is a PC relative load.  Add a fixup.&lt;br /&gt;
    Fixups.push_back(MCFixup::create(&lt;br /&gt;
        0, offsetOp.getExpr(),&lt;br /&gt;
        MCFixupKind(NuPlus::fixup_NuPlus_PCRel_Lea)));&lt;br /&gt;
  } else if (offsetOp.isImm())&lt;br /&gt;
    encoding |= static_cast&amp;lt;short&amp;gt;(offsetOp.getImm())&amp;lt;&amp;lt;1;&lt;br /&gt;
  else&lt;br /&gt;
    assert(offsetOp.isImm() &amp;amp;&amp;amp; &amp;quot;Second operand of LEA op is unknown type.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return encoding;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Encode NuPlus Memory Operand.  The result is a packed field with the&lt;br /&gt;
// register in the low 5 bits and the offset in the remainder.  The instruction&lt;br /&gt;
// patterns will put these into the proper part of the instruction&lt;br /&gt;
// (NuPlusInstrFormats.td).&lt;br /&gt;
unsigned&lt;br /&gt;
NuPlusMCCodeEmitter::encodeMemoryOpValue(const MCInst &amp;amp;MI, unsigned Op,&lt;br /&gt;
                                        SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
                                        const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
  unsigned encoding;&lt;br /&gt;
&lt;br /&gt;
  MCOperand baseReg;&lt;br /&gt;
  MCOperand offsetOp;&lt;br /&gt;
&lt;br /&gt;
  baseReg = MI.getOperand(1);&lt;br /&gt;
  offsetOp = MI.getOperand(2); &lt;br /&gt;
  &lt;br /&gt;
  // Register&lt;br /&gt;
  // This is register/offset.  No need for relocation.&lt;br /&gt;
  assert(baseReg.isReg() &amp;amp;&amp;amp; &amp;quot;First operand is not register.&amp;quot;);&lt;br /&gt;
  //encoding just the register&lt;br /&gt;
  encoding = Ctx.getRegisterInfo()-&amp;gt;getEncodingValue(baseReg.getReg());&lt;br /&gt;
  // Offset&lt;br /&gt;
  if (offsetOp.isExpr()) {&lt;br /&gt;
    // Load with a label. This is a PC relative load.  Add a fixup.&lt;br /&gt;
    // XXX Note that this assumes unmasked instructions.  A masked&lt;br /&gt;
    // instruction will not work and should not be used. Check for this&lt;br /&gt;
    // and return an error.&lt;br /&gt;
    Fixups.push_back(&lt;br /&gt;
        MCFixup::create(0, offsetOp.getExpr(),&lt;br /&gt;
                        MCFixupKind(NuPlus::fixup_NuPlus_PCRel_Mem)));&lt;br /&gt;
  } else if (offsetOp.isImm())&lt;br /&gt;
    encoding |= static_cast&amp;lt;short&amp;gt;(offsetOp.getImm()) &amp;lt;&amp;lt; 6;&lt;br /&gt;
  else&lt;br /&gt;
    assert(offsetOp.isImm() &amp;amp;&amp;amp; &amp;quot;Second operand of memory op is unknown type.&amp;quot;);&lt;br /&gt;
  return encoding;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// encodeBranchTargetOpValue - Return binary encoding of the jump&lt;br /&gt;
// target operand. If the machine operand requires relocation,&lt;br /&gt;
// record the relocation and return zero.&lt;br /&gt;
unsigned NuPlusMCCodeEmitter::encodeBranchTargetOpValue(&lt;br /&gt;
    const MCInst &amp;amp;MI, unsigned OpNo, SmallVectorImpl&amp;lt;MCFixup&amp;gt; &amp;amp;Fixups,&lt;br /&gt;
    const MCSubtargetInfo &amp;amp;STI) const {&lt;br /&gt;
&lt;br /&gt;
  const MCOperand &amp;amp;MO = MI.getOperand(OpNo);&lt;br /&gt;
  if (MO.isImm())&lt;br /&gt;
    return MO.getImm();&lt;br /&gt;
&lt;br /&gt;
  assert(MO.isExpr() &amp;amp;&amp;amp;&lt;br /&gt;
         &amp;quot;encodeBranchTargetOpValue expects only expressions or an immediate&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  const MCExpr *Expr = MO.getExpr();&lt;br /&gt;
  Fixups.push_back(&lt;br /&gt;
      MCFixup::create(0, Expr, MCFixupKind(NuPlus::fixup_NuPlus_Branch)));&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusGenMCCodeEmitter.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusMCCodeEmitter.cpp&amp;diff=2126</id>
		<title>NuPlusMCCodeEmitter.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusMCCodeEmitter.cpp&amp;diff=2126"/>
				<updated>2019-06-21T14:51:21Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusMCCodeEmitter.cpp to NaplesPUMCCodeEmitter.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUMCCodeEmitter.cpp]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUInstPrinter.cpp&amp;diff=2123</id>
		<title>NaplesPUInstPrinter.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUInstPrinter.cpp&amp;diff=2123"/>
				<updated>2019-06-21T14:49:34Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusInstPrinter.cpp to NaplesPUInstPrinter.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;NuPlusInstPrinter contains method to print assembly instructions from MCInst objects. &lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusInstPrinter.cpp - Convert NuPlus MCInst to assembly syntax -----==//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This class prints an NuPlus MCInst to a .s file.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusInstPrinter.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NuPlusMCTargetDesc.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NuPlusInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/ADT/StringExtras.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCExpr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInst.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCRegisterInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSymbol.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/ErrorHandling.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#define DEBUG_TYPE &amp;quot;asm-printer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusGenAsmWriter.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
namespace&lt;br /&gt;
{&lt;br /&gt;
void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,&lt;br /&gt;
               raw_ostream &amp;amp;OS)&lt;br /&gt;
{&lt;br /&gt;
  int Offset = 0;&lt;br /&gt;
  const MCSymbolRefExpr *SRE;&lt;br /&gt;
&lt;br /&gt;
  if (const MCBinaryExpr *BE = dyn_cast&amp;lt;MCBinaryExpr&amp;gt;(Expr))&lt;br /&gt;
  {&lt;br /&gt;
    SRE = dyn_cast&amp;lt;MCSymbolRefExpr&amp;gt;(BE-&amp;gt;getLHS());&lt;br /&gt;
    const MCConstantExpr *CE = dyn_cast&amp;lt;MCConstantExpr&amp;gt;(BE-&amp;gt;getRHS());&lt;br /&gt;
    assert(SRE &amp;amp;&amp;amp; CE &amp;amp;&amp;amp; &amp;quot;Binary expression must be sym+const.&amp;quot;);&lt;br /&gt;
    Offset = CE-&amp;gt;getValue();&lt;br /&gt;
  }&lt;br /&gt;
  else if (!(SRE = dyn_cast&amp;lt;MCSymbolRefExpr&amp;gt;(Expr)))&lt;br /&gt;
  {&lt;br /&gt;
    Expr-&amp;gt;print(OS, MAI);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  MCSymbolRefExpr::VariantKind Kind = SRE-&amp;gt;getKind();&lt;br /&gt;
&lt;br /&gt;
  OS &amp;lt;&amp;lt; SRE-&amp;gt;getSymbol();&lt;br /&gt;
&lt;br /&gt;
  if (Offset)&lt;br /&gt;
  {&lt;br /&gt;
    if (Offset &amp;gt; 0)&lt;br /&gt;
      OS &amp;lt;&amp;lt; '+';&lt;br /&gt;
    OS &amp;lt;&amp;lt; Offset;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (Kind != MCSymbolRefExpr::VK_None)&lt;br /&gt;
    OS &amp;lt;&amp;lt; ')';&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusInstPrinter::printRegName(raw_ostream &amp;amp;OS, unsigned RegNo) const&lt;br /&gt;
{&lt;br /&gt;
  // TODO: (Catello) magic errs()&lt;br /&gt;
  //errs()&amp;lt;&amp;lt; &amp;quot;&amp;quot;;&lt;br /&gt;
  OS &amp;lt;&amp;lt; StringRef(getRegisterName(RegNo)).lower();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusInstPrinter::printInst(const MCInst *MI, raw_ostream &amp;amp;O,&lt;br /&gt;
                                  StringRef Annot, const MCSubtargetInfo &amp;amp;STI)&lt;br /&gt;
{&lt;br /&gt;
  // NOP is or s0, s0, 0&lt;br /&gt;
  if (MI-&amp;gt;getOpcode() == NuPlus::ORSSI &amp;amp;&amp;amp; MI-&amp;gt;getOperand(0).isReg() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(0).getReg() == NuPlus::S0 &amp;amp;&amp;amp; MI-&amp;gt;getOperand(1).isReg() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(1).getReg() == NuPlus::S0 &amp;amp;&amp;amp; MI-&amp;gt;getOperand(2).isImm() &amp;amp;&amp;amp;&lt;br /&gt;
      MI-&amp;gt;getOperand(2).getImm() == 0)&lt;br /&gt;
  {&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;\tnop&amp;quot;;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  printInstruction(MI, O);&lt;br /&gt;
  printAnnotation(O, Annot);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusInstPrinter::printOperand(const MCInst *MI, int opNum,&lt;br /&gt;
                                     raw_ostream &amp;amp;O)&lt;br /&gt;
{&lt;br /&gt;
  const MCOperand &amp;amp;MO = MI-&amp;gt;getOperand(opNum);&lt;br /&gt;
&lt;br /&gt;
  if (MO.isReg())&lt;br /&gt;
  {&lt;br /&gt;
    printRegName(O, MO.getReg());&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (MO.isImm())&lt;br /&gt;
  {&lt;br /&gt;
    O &amp;lt;&amp;lt; (int)MO.getImm();&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  assert(MO.isExpr() &amp;amp;&amp;amp; &amp;quot;Unknown operand kind in printOperand&amp;quot;);&lt;br /&gt;
  if (MO.isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    printExpr(MO.getExpr(), &amp;amp;MAI, O);&lt;br /&gt;
  }&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusInstPrinter::printMemOperand(const MCInst *MI, int opNum,&lt;br /&gt;
                                        raw_ostream &amp;amp;O)&lt;br /&gt;
{&lt;br /&gt;
   if (MI-&amp;gt;getOperand(opNum).isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    // Abs instructions&lt;br /&gt;
    printOperand(MI, opNum, O);&lt;br /&gt;
  }&lt;br /&gt;
  else if (MI-&amp;gt;getOperand(opNum + 1).isExpr())&lt;br /&gt;
  {&lt;br /&gt;
    // PC relative memory access to a local label&lt;br /&gt;
    printOperand(MI, opNum + 1, O);&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    // Register/offset&lt;br /&gt;
    assert(MI-&amp;gt;getOperand(opNum).isReg());&lt;br /&gt;
    assert(MI-&amp;gt;getOperand(opNum + 1).isImm());&lt;br /&gt;
&lt;br /&gt;
    if (MI-&amp;gt;getOperand(opNum + 1).getImm())&lt;br /&gt;
      printOperand(MI, opNum + 1, O);&lt;br /&gt;
&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;(&amp;quot;;&lt;br /&gt;
    printOperand(MI, opNum, O);&lt;br /&gt;
    O &amp;lt;&amp;lt; &amp;quot;)&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusInstPrinter.cpp&amp;diff=2124</id>
		<title>NuPlusInstPrinter.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusInstPrinter.cpp&amp;diff=2124"/>
				<updated>2019-06-21T14:49:34Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusInstPrinter.cpp to NaplesPUInstPrinter.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUInstPrinter.cpp]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUMCInstLower.cpp&amp;diff=2121</id>
		<title>NaplesPUMCInstLower.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUMCInstLower.cpp&amp;diff=2121"/>
				<updated>2019-06-21T14:49:12Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusMCInstLower.cpp to NaplesPUMCInstLower.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The NuPlusMCInstLower class transforms the MachineInstr object into a simplified version, the MCInst one. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusMCInstLower.cpp - Convert NuPlus MachineInstr to MCInst -------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This file contains code to lower NuPlus MachineInstrs to their corresponding&lt;br /&gt;
// MCInst records.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusAsmPrinter.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NuPlusInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NuPlusMCInstLower.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineFunction.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineInstr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineOperand.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCContext.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCExpr.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCInst.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/MC/MCSymbol.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define GET_REGINFO_ENUM&lt;br /&gt;
#include &amp;quot;NuPlusGenRegisterInfo.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
NuPlusMCInstLower::NuPlusMCInstLower(NuPlusAsmPrinter &amp;amp;asmprinter)&lt;br /&gt;
  : AsmPrinter(asmprinter) {}&lt;br /&gt;
&lt;br /&gt;
void NuPlusMCInstLower::Initialize(MCContext *C) {&lt;br /&gt;
  Ctx = C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Derived from MipsMCInstLower&lt;br /&gt;
MCOperand NuPlusMCInstLower::LowerSymbolOperand(const MachineOperand &amp;amp;MO,&lt;br /&gt;
                                              MachineOperandType MOTy,&lt;br /&gt;
                                              unsigned Offset) const {&lt;br /&gt;
  MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;&lt;br /&gt;
  const MCSymbol *Symbol;&lt;br /&gt;
&lt;br /&gt;
  switch (MOTy) {&lt;br /&gt;
  case MachineOperand::MO_MachineBasicBlock:&lt;br /&gt;
    Symbol = MO.getMBB()-&amp;gt;getSymbol();&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  case MachineOperand::MO_GlobalAddress:&lt;br /&gt;
    Symbol = AsmPrinter.getSymbol(MO.getGlobal());&lt;br /&gt;
    Offset += MO.getOffset();&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  case MachineOperand::MO_BlockAddress:&lt;br /&gt;
    Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());&lt;br /&gt;
    Offset += MO.getOffset();&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  case MachineOperand::MO_ExternalSymbol:&lt;br /&gt;
    Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());&lt;br /&gt;
    Offset += MO.getOffset();&lt;br /&gt;
    break;&lt;br /&gt;
  case MachineOperand::MO_JumpTableIndex:&lt;br /&gt;
    Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());&lt;br /&gt;
    break;&lt;br /&gt;
  case MachineOperand::MO_ConstantPoolIndex:&lt;br /&gt;
    Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());&lt;br /&gt;
    Offset += MO.getOffset();&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  default:&lt;br /&gt;
    llvm_unreachable(&amp;quot;&amp;lt;unknown operand type&amp;gt;&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //TODO: controllare differenze con MIPS e come mai nel case manca MO_MCSymbol (anche nella funzione successiva)&lt;br /&gt;
  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);&lt;br /&gt;
  if (!Offset)&lt;br /&gt;
    return MCOperand::createExpr(MCSym);&lt;br /&gt;
&lt;br /&gt;
  // Assume offset is never negative.&lt;br /&gt;
  assert(Offset &amp;gt; 0);&lt;br /&gt;
  const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx);&lt;br /&gt;
  const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);&lt;br /&gt;
  return MCOperand::createExpr(Add);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
MCOperand NuPlusMCInstLower::LowerOperand(const MachineOperand &amp;amp;MO,&lt;br /&gt;
                                        unsigned offset) const {&lt;br /&gt;
  MachineOperandType MOTy = MO.getType();&lt;br /&gt;
&lt;br /&gt;
  switch (MOTy) {&lt;br /&gt;
  default: llvm_unreachable(&amp;quot;unknown operand type&amp;quot;);&lt;br /&gt;
  case MachineOperand::MO_Register:&lt;br /&gt;
    // Ignore all implicit register operands.&lt;br /&gt;
    if (MO.isImplicit()) break;&lt;br /&gt;
    return MCOperand::createReg(MO.getReg());&lt;br /&gt;
  case MachineOperand::MO_Immediate:&lt;br /&gt;
    return MCOperand::createImm(MO.getImm() + offset);&lt;br /&gt;
  case MachineOperand::MO_MachineBasicBlock:&lt;br /&gt;
  case MachineOperand::MO_GlobalAddress:&lt;br /&gt;
  case MachineOperand::MO_ExternalSymbol:&lt;br /&gt;
  case MachineOperand::MO_JumpTableIndex:&lt;br /&gt;
  case MachineOperand::MO_ConstantPoolIndex:&lt;br /&gt;
  case MachineOperand::MO_BlockAddress:&lt;br /&gt;
    return LowerSymbolOperand(MO, MOTy, offset);&lt;br /&gt;
  case MachineOperand::MO_RegisterMask:&lt;br /&gt;
    break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
  return MCOperand();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void NuPlusMCInstLower::Lower(const MachineInstr *MI, MCInst &amp;amp;OutMI) const {&lt;br /&gt;
  OutMI.setOpcode(MI-&amp;gt;getOpcode());&lt;br /&gt;
&lt;br /&gt;
  // XXX note that this chunk of code assumes a load instruction. It's also&lt;br /&gt;
  // possible for MO_ConstantPoolIndex to appear in arithmetic.  In this&lt;br /&gt;
  // situation, the instruction would be clobbered.&lt;br /&gt;
  //TODO: questo if usato nel caso in cui l'istruzione usa costantpool o jumptable. &lt;br /&gt;
  // noi non abbiamo la jump table. E la costant pool?? controllare e modificare&lt;br /&gt;
  if (MI-&amp;gt;getNumOperands() &amp;gt; 1 &amp;amp;&amp;amp;&lt;br /&gt;
      (MI-&amp;gt;getOperand(1).getType() == MachineOperand::MO_ConstantPoolIndex ||&lt;br /&gt;
       MI-&amp;gt;getOperand(1).getType() == MachineOperand::MO_JumpTableIndex)) {&lt;br /&gt;
    OutMI.addOperand(LowerOperand(MI-&amp;gt;getOperand(0))); // result&lt;br /&gt;
&lt;br /&gt;
    const MachineOperand &amp;amp;cpEntry = MI-&amp;gt;getOperand(1);&lt;br /&gt;
&lt;br /&gt;
    // This is a PC relative constant pool access.  Add the PC register&lt;br /&gt;
    // to this instruction to match what the assembly parser produces&lt;br /&gt;
    // (and InstPrinter/Encoder expects)&lt;br /&gt;
    // It should look like this:&lt;br /&gt;
    // &amp;lt;MCInst #97 LWi &amp;lt;MCOperand Reg:8&amp;gt; &amp;lt;MCOperand Reg:3&amp;gt; &amp;lt;MCOperand&lt;br /&gt;
    // Expr:(foo)&amp;gt;&amp;gt;&lt;br /&gt;
    OutMI.addOperand(MCOperand::createReg(NuPlus::PC_REG));&lt;br /&gt;
    const MCSymbol *Symbol;&lt;br /&gt;
    if (MI-&amp;gt;getOperand(1).getType() == MachineOperand::MO_ConstantPoolIndex)&lt;br /&gt;
      Symbol = AsmPrinter.GetCPISymbol(cpEntry.getIndex());&lt;br /&gt;
    else&lt;br /&gt;
      Symbol = AsmPrinter.GetJTISymbol(cpEntry.getIndex());&lt;br /&gt;
&lt;br /&gt;
    const MCSymbolRefExpr *MCSym =&lt;br /&gt;
        MCSymbolRefExpr::create(Symbol, MCSymbolRefExpr::VK_None, *Ctx);&lt;br /&gt;
    MCOperand MCOp = MCOperand::createExpr(MCSym);&lt;br /&gt;
    OutMI.addOperand(MCOp);&lt;br /&gt;
  } else {&lt;br /&gt;
    for (unsigned i = 0, e = MI-&amp;gt;getNumOperands(); i != e; ++i) {&lt;br /&gt;
      const MachineOperand &amp;amp;MO = MI-&amp;gt;getOperand(i);&lt;br /&gt;
      MCOperand MCOp = LowerOperand(MO);&lt;br /&gt;
&lt;br /&gt;
      if (MCOp.isValid())&lt;br /&gt;
        OutMI.addOperand(MCOp);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusMCInstLower.cpp&amp;diff=2122</id>
		<title>NuPlusMCInstLower.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusMCInstLower.cpp&amp;diff=2122"/>
				<updated>2019-06-21T14:49:12Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusMCInstLower.cpp to NaplesPUMCInstLower.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUMCInstLower.cpp]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUFrameLowering.cpp&amp;diff=2119</id>
		<title>NaplesPUFrameLowering.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUFrameLowering.cpp&amp;diff=2119"/>
				<updated>2019-06-21T14:48:45Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusFrameLowering.cpp to NaplesPUFrameLowering.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C++ Classes]]&lt;br /&gt;
The NuPlusFrameLowering class must handle all the operations concerning the stack frame. It implements the '''TargetFrameLowering''' interface. &lt;br /&gt;
In nu+ the stack grows incrementing the address (i.e. the stack grows down) and it is 64-byte aligned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusFrameLowering.cpp - NuPlus Frame Information -----------------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This file contains the NuPlus implementation of TargetFrameLowering&lt;br /&gt;
// class.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusFrameLowering.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MCTargetDesc/NuPlusMCTargetDesc.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NuPlusInstrInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;NuPlusMachineFunctionInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineFrameInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineFunction.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineInstrBuilder.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineModuleInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/MachineRegisterInfo.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/RegisterScavenging.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/IR/DataLayout.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/IR/Function.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/CommandLine.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Target/TargetOptions.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
void NuPlusFrameLowering::emitPrologue(MachineFunction &amp;amp;MF,&lt;br /&gt;
                                      MachineBasicBlock &amp;amp;MBB) const {&lt;br /&gt;
  assert(&amp;amp;MF.front() == &amp;amp;MBB);&lt;br /&gt;
  MachineFrameInfo &amp;amp;MFI = MF.getFrameInfo();&lt;br /&gt;
  const NuPlusInstrInfo &amp;amp;TII =&lt;br /&gt;
      *static_cast&amp;lt;const NuPlusInstrInfo *&amp;gt;(MF.getSubtarget().getInstrInfo());&lt;br /&gt;
  const MCRegisterInfo *MRI = MF.getMMI().getContext().getRegisterInfo();&lt;br /&gt;
  MachineBasicBlock::iterator MBBI = MBB.begin();&lt;br /&gt;
&lt;br /&gt;
  // Debug location must be unknown since the first debug location is used&lt;br /&gt;
  // to determine the end of the prologue.&lt;br /&gt;
  DebugLoc DL;&lt;br /&gt;
&lt;br /&gt;
  // Compute stack size to allocate, keeping SP 64 byte aligned so we&lt;br /&gt;
  // can do block vector load/stores&lt;br /&gt;
  int StackSize = alignTo(MFI.getStackSize(), getStackAlignment());&lt;br /&gt;
&lt;br /&gt;
  // Bail if there is no stack allocation&lt;br /&gt;
  if (StackSize == 0 &amp;amp;&amp;amp; !MFI.adjustsStack())&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  TII.adjustStackPointer(MBB, MBBI, DL, -StackSize);&lt;br /&gt;
&lt;br /&gt;
  // Emit DW_CFA_def_cfa&lt;br /&gt;
  unsigned CFIIndex = MF.addFrameInst(&lt;br /&gt;
      MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize));&lt;br /&gt;
  BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))&lt;br /&gt;
      .addCFIIndex(CFIIndex);&lt;br /&gt;
&lt;br /&gt;
  // Find the instruction past the last instruction that saves a callee-saved&lt;br /&gt;
  // register to the stack.  We need to set up FP after its old value has been&lt;br /&gt;
  // saved.&lt;br /&gt;
  const std::vector&amp;lt;CalleeSavedInfo&amp;gt; &amp;amp;CSI = MFI.getCalleeSavedInfo();&lt;br /&gt;
  if (CSI.size()) {&lt;br /&gt;
    for (unsigned i = 0; i &amp;lt; CSI.size(); ++i)&lt;br /&gt;
      ++MBBI;&lt;br /&gt;
&lt;br /&gt;
    // Iterate over list of callee-saved registers and emit .cfi_offset&lt;br /&gt;
    // directives (debug information)&lt;br /&gt;
    for (const auto &amp;amp;I : CSI) {&lt;br /&gt;
      int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());&lt;br /&gt;
      unsigned Reg = I.getReg();&lt;br /&gt;
      unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(&lt;br /&gt;
          nullptr, MRI-&amp;gt;getDwarfRegNum(Reg, 1), Offset));&lt;br /&gt;
      BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))&lt;br /&gt;
          .addCFIIndex(CFIIndex);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // fp = sp&lt;br /&gt;
  if (hasFP(MF)) {&lt;br /&gt;
    BuildMI(MBB, MBBI, DL, TII.get(NuPlus::MOVE_SS_32))&lt;br /&gt;
        .addReg(NuPlus::FP_REG)&lt;br /&gt;
        .addReg(NuPlus::SP_REG);&lt;br /&gt;
&lt;br /&gt;
    // emit &amp;quot;.cfi_def_cfa_register $fp&amp;quot; (debug information)&lt;br /&gt;
    unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(&lt;br /&gt;
        nullptr, MRI-&amp;gt;getDwarfRegNum(NuPlus::FP_REG, true)));&lt;br /&gt;
    BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))&lt;br /&gt;
        .addCFIIndex(CFIIndex);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusFrameLowering::emitEpilogue(MachineFunction &amp;amp;MF,&lt;br /&gt;
                                      MachineBasicBlock &amp;amp;MBB) const {&lt;br /&gt;
  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();&lt;br /&gt;
  MachineFrameInfo &amp;amp;MFI = MF.getFrameInfo();&lt;br /&gt;
  const NuPlusInstrInfo &amp;amp;TII =&lt;br /&gt;
      *static_cast&amp;lt;const NuPlusInstrInfo *&amp;gt;(MF.getSubtarget().getInstrInfo());&lt;br /&gt;
  DebugLoc DL = MBBI-&amp;gt;getDebugLoc();&lt;br /&gt;
  assert(MBBI-&amp;gt;getOpcode() == NuPlus::JRET &amp;amp;&amp;amp;&lt;br /&gt;
         &amp;quot;Can only put epilog before 'retl' instruction!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // if framepointer enabled, restore the stack pointer.&lt;br /&gt;
  if (hasFP(MF)) {&lt;br /&gt;
    // Find the first instruction that restores a callee-saved register.&lt;br /&gt;
    MachineBasicBlock::iterator I = MBBI;&lt;br /&gt;
    for (unsigned i = 0; i &amp;lt; MFI.getCalleeSavedInfo().size(); ++i)&lt;br /&gt;
      --I;&lt;br /&gt;
&lt;br /&gt;
    BuildMI(MBB, I, DL, TII.get(NuPlus::MOVE_SS_32))&lt;br /&gt;
        .addReg(NuPlus::SP_REG)&lt;br /&gt;
        .addReg(NuPlus::FP_REG);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  uint64_t StackSize = alignTo(MFI.getStackSize(), getStackAlignment());&lt;br /&gt;
  if (!StackSize)&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  TII.adjustStackPointer(MBB, MBBI, DL, StackSize);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
MachineBasicBlock::iterator NuPlusFrameLowering::eliminateCallFramePseudoInstr(&lt;br /&gt;
    MachineFunction &amp;amp;MF, MachineBasicBlock &amp;amp;MBB,&lt;br /&gt;
    MachineBasicBlock::iterator MBBI) const {&lt;br /&gt;
  MachineInstr &amp;amp;MI = *MBBI;&lt;br /&gt;
&lt;br /&gt;
  const NuPlusInstrInfo &amp;amp;TII =&lt;br /&gt;
      *static_cast&amp;lt;const NuPlusInstrInfo *&amp;gt;(MF.getSubtarget().getInstrInfo());&lt;br /&gt;
&lt;br /&gt;
  // Note the check for hasReservedCallFrame.  If it returns true,&lt;br /&gt;
  // PEI::calculateFrameObjectOffsets has already reserved stack locations for&lt;br /&gt;
  // these variables and we don't need to adjust the stack here.&lt;br /&gt;
  int Amount = TII.getFrameSize(MI);&lt;br /&gt;
  if (Amount != 0 &amp;amp;&amp;amp; !hasReservedCallFrame(MF)) {&lt;br /&gt;
    assert(hasFP(MF) &amp;amp;&amp;amp;&lt;br /&gt;
           &amp;quot;Cannot adjust stack mid-function without a frame pointer&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    if (MI.getOpcode() == NuPlus::ADJCALLSTACKDOWN)&lt;br /&gt;
      Amount = -Amount;&lt;br /&gt;
&lt;br /&gt;
    TII.adjustStackPointer(MBB, MBBI, MBBI-&amp;gt;getDebugLoc(), Amount);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return MBB.erase(MBBI);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusFrameLowering::determineCalleeSaves(MachineFunction &amp;amp;MF,&lt;br /&gt;
                                              BitVector &amp;amp;SavedRegs,&lt;br /&gt;
                                              RegScavenger *RS) const {&lt;br /&gt;
&lt;br /&gt;
  TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);&lt;br /&gt;
  if (hasFP(MF))&lt;br /&gt;
    SavedRegs.set(NuPlus::FP_REG);&lt;br /&gt;
&lt;br /&gt;
  // The register scavenger allows us to allocate virtual registers during&lt;br /&gt;
  // epilogue/prologue insertion, after register allocation has run. We only&lt;br /&gt;
  // need to do this if the frame is too large to be addressed by immediate&lt;br /&gt;
  // offsets. If it isn't, don't bother creating a stack slot for it.&lt;br /&gt;
  // This may create the scavenge slot when it isn't needed.&lt;br /&gt;
  // This check must match the size of the one in&lt;br /&gt;
  // NuPlusRegisterInfo::eliminateFrameIndex&lt;br /&gt;
  if (isInt&amp;lt;9&amp;gt;(getWorstCaseStackSize(MF)))&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();&lt;br /&gt;
  const TargetRegisterClass &amp;amp;RC = NuPlus::GPR32RegClass;&lt;br /&gt;
  int FI = MF.getFrameInfo().CreateStackObject(TRI-&amp;gt;getSpillSize(RC),&lt;br /&gt;
                                               TRI-&amp;gt;getSpillAlignment(RC), false);&lt;br /&gt;
  RS-&amp;gt;addScavengingFrameIndex(FI);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// We must use an FP in a few situations.  Note that this *must* return true if&lt;br /&gt;
// hasReservedCallFrame returns false.  Otherwise an ADJCALLSTACKDOWN could mess&lt;br /&gt;
// up frame offsets from the stack pointer.&lt;br /&gt;
bool NuPlusFrameLowering::hasFP(const MachineFunction &amp;amp;MF) const {&lt;br /&gt;
  const MachineFrameInfo &amp;amp;MFI = MF.getFrameInfo();&lt;br /&gt;
  return MF.getTarget().Options.DisableFramePointerElim(MF) ||&lt;br /&gt;
         MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns true if the prologue inserter should reserve space for outgoing&lt;br /&gt;
// arguments to called.&lt;br /&gt;
bool NuPlusFrameLowering::hasReservedCallFrame(const MachineFunction &amp;amp;MF) const {&lt;br /&gt;
  return !MF.getFrameInfo().hasVarSizedObjects();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint64_t&lt;br /&gt;
NuPlusFrameLowering::getWorstCaseStackSize(const MachineFunction &amp;amp;MF) const {&lt;br /&gt;
  const MachineFrameInfo &amp;amp;MFI = MF.getFrameInfo();&lt;br /&gt;
  const TargetRegisterInfo &amp;amp;TRI = *MF.getSubtarget().getRegisterInfo();&lt;br /&gt;
&lt;br /&gt;
  int64_t Offset = 0;&lt;br /&gt;
&lt;br /&gt;
  // Iterate over fixed sized objects.&lt;br /&gt;
  for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)&lt;br /&gt;
    Offset = std::max(Offset, -MFI.getObjectOffset(I));&lt;br /&gt;
&lt;br /&gt;
  // Conservatively assume all callee-saved registers will be saved.&lt;br /&gt;
  for (const uint16_t *R = TRI.getCalleeSavedRegs(&amp;amp;MF); *R; ++R) {&lt;br /&gt;
    const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(*R);&lt;br /&gt;
    unsigned Size = TRI.getRegSizeInBits(*RC);&lt;br /&gt;
    Offset = alignTo(Offset + Size, Size);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  unsigned MaxAlign = MFI.getMaxAlignment();&lt;br /&gt;
&lt;br /&gt;
  // Check that MaxAlign is not zero if there is a stack object that is not a&lt;br /&gt;
  // callee-saved spill.&lt;br /&gt;
  assert(!MFI.getObjectIndexEnd() || MaxAlign);&lt;br /&gt;
&lt;br /&gt;
  // Iterate over other objects.&lt;br /&gt;
  for (unsigned I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I)&lt;br /&gt;
    Offset = alignTo(Offset + MFI.getObjectSize(I), MaxAlign);&lt;br /&gt;
&lt;br /&gt;
  // Call frame.&lt;br /&gt;
  if (MFI.adjustsStack() &amp;amp;&amp;amp; hasReservedCallFrame(MF))&lt;br /&gt;
    Offset = alignTo(Offset + MFI.getMaxCallFrameSize(),&lt;br /&gt;
                     std::max(MaxAlign, getStackAlignment()));&lt;br /&gt;
&lt;br /&gt;
  return alignTo(Offset, getStackAlignment());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusFrameLowering.cpp&amp;diff=2120</id>
		<title>NuPlusFrameLowering.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusFrameLowering.cpp&amp;diff=2120"/>
				<updated>2019-06-21T14:48:45Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusFrameLowering.cpp to NaplesPUFrameLowering.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUFrameLowering.cpp]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUISelLowering.cpp&amp;diff=2115</id>
		<title>NaplesPUISelLowering.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUISelLowering.cpp&amp;diff=2115"/>
				<updated>2019-06-21T14:43:32Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusISelLowering.cpp to NaplesPUISelLowering.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=NuPlusTargetLowering class=&lt;br /&gt;
[[Category:C++ Classes]]&lt;br /&gt;
The '''NuPlusTargetLowering''' class implements the [http://llvm.org/docs/CodeGenerator.html#the-targetlowering-class TargetLowering] interface and is contained in the NuPlusISelLowering.h/.cpp files. &lt;br /&gt;
The class must describe how to lower LLVM code to machine code. This has two main components:&lt;br /&gt;
#Which ValueTypes are natively supported by the target.&lt;br /&gt;
#Which operations are supported for supported ValueTypes.&lt;br /&gt;
&lt;br /&gt;
The '''NuPlusTargetLowering''' class can be thought of being composed by four sections:&lt;br /&gt;
#The class constructor.&lt;br /&gt;
#The custom [https://llvm.org/docs/CodeGenerator.html#introduction-to-selectiondags SDNode] lowering.&lt;br /&gt;
#The custom [http://llvm.org/docs/CodeGenerator.html#machineinstr MachineInstruction] insertion.&lt;br /&gt;
#The implementation of other TargetLowering virtual methods.&lt;br /&gt;
&lt;br /&gt;
== The Class Constructor ==&lt;br /&gt;
The NuPlusTargetLowering class constructor describes the MachineValueTypes supported by nu+ with the corresponding [[NuPlusRegisterInfo.td |RegisterClass]], the operations not supported for supported MachineValueTypes and the corresponding action to perform, other useful information concerning the Instruction-Lowering phase.&lt;br /&gt;
These informations are described using the ''protected'' methods provided by the base class ''TargetLowering''. &lt;br /&gt;
&lt;br /&gt;
=== addRegisterClass ===&lt;br /&gt;
The '''addRegisterClass''' method tells the Code Generator the supported MachineValueTypes and the RegisterClass to use. The '''MachineValueTypes''' are defined in the '''MVT''' class in &amp;quot;compiler/include/llvm/CodeGen/MachineValueType.h&amp;quot;, while the RegisterClass are those defined in [[NuPlusRegisterInfo.td]]. The following table summarize the supported MachineValueTypes and the relative RegisterClass.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;font-weight: bold;&amp;quot; | RegisterClass&lt;br /&gt;
! style=&amp;quot;font-weight: bold;&amp;quot; | MVT&lt;br /&gt;
|-&lt;br /&gt;
| GPR32RegClass&lt;br /&gt;
| i32, f32&lt;br /&gt;
|-&lt;br /&gt;
| GPR64RegClass&lt;br /&gt;
| i64, f64&lt;br /&gt;
|-&lt;br /&gt;
| VR512WRegClass&lt;br /&gt;
| v16i32, v16f32&lt;br /&gt;
|-&lt;br /&gt;
| VR512LRegClass&lt;br /&gt;
| v8i64, v8f64&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The corresponding code is:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
  // Scalar data types&lt;br /&gt;
  addRegisterClass(MVT::i32, &amp;amp;NuPlus::GPR32RegClass);&lt;br /&gt;
  addRegisterClass(MVT::f32, &amp;amp;NuPlus::GPR32RegClass);&lt;br /&gt;
&lt;br /&gt;
  addRegisterClass(MVT::i64, &amp;amp;NuPlus::GPR64RegClass);&lt;br /&gt;
  addRegisterClass(MVT::f64, &amp;amp;NuPlus::GPR64RegClass);&lt;br /&gt;
&lt;br /&gt;
  // Vector data types (512-bit wide)&lt;br /&gt;
  addRegisterClass(MVT::v16i32, &amp;amp;NuPlus::VR512WRegClass);&lt;br /&gt;
  addRegisterClass(MVT::v16f32, &amp;amp;NuPlus::VR512WRegClass);&lt;br /&gt;
&lt;br /&gt;
  addRegisterClass(MVT::v8i64, &amp;amp;NuPlus::VR512LRegClass);&lt;br /&gt;
  addRegisterClass(MVT::v8f64, &amp;amp;NuPlus::VR512LRegClass);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== setOperationAction ===&lt;br /&gt;
The '''setOperationAction''' method is used to tell the Code Generator the unsupported operation for the specified MachineValueType and the action to perform, this because by default every operation is considered '''Legal'''.&lt;br /&gt;
&lt;br /&gt;
This information is used by the LLVM Code Generator during the [http://llvm.org/docs/CodeGenerator.html#instruction-selection-section InstructionSelection] phase. So the input to give the function are the '''Operation Code''' (defined in the '''NodeType''' enum in &amp;quot;/compiler/include/llvm/CodeGen/ISDOpcodes.h&amp;quot;), the associated '''MachineValueTypes''' and the '''action''' to perform in order to legalize the operation. At this stage each operation is described by a Node in the SelectionDAG.&lt;br /&gt;
&lt;br /&gt;
The action must be one of those in the '''LegalizeAction''' enum contained in the '''TargetLoweringBase''' class (/compiler/include/llvm/Target/TargetLowering.h). Hence the possible actions are:&lt;br /&gt;
* '''Legal''', the target natively supports this operation.&lt;br /&gt;
* '''Promote''', this operation should be executed in a larger type.&lt;br /&gt;
* '''Expand''', try to expand this to other ops, otherwise use a libcall.&lt;br /&gt;
* '''LibCall''', don't try to expand this to other ops, always use a libcall.&lt;br /&gt;
* '''Custom''', use the '''LowerOperation''' hook to implement custom lowering.&lt;br /&gt;
&lt;br /&gt;
The most used in the nu++ backend are the ''Expand'' and the ''Custom'' actions.&lt;br /&gt;
As mentioned before, the '''Expand''' action tries to expand the node using equivalent operations, if this cannot be done, a function call is generated. The signature is defined in the '''InitLibcallNames''' in &amp;quot;/compiler/lib/CodeGen/TargetLoweringBase.cpp&amp;quot;.&lt;br /&gt;
With the '''Custom''' action, the lowering must be manually done implementing a proper function.&lt;br /&gt;
&lt;br /&gt;
== Custom Lowering ==&lt;br /&gt;
&lt;br /&gt;
When an operation must be custom lowered (using setOperationAction with Custom action), LLVM calls the '''LowerOperation''' function passing it the Node to lower and the DAG. The lowering is handled in this way:&lt;br /&gt;
*The '''LowerOperation''' function is implemented with a switch on the Node Opcode, according to its value returns the SDValue of a specific function.&lt;br /&gt;
*The operand specific functions are named as ''LowerOPERAND_NAME'' and they must generate the Machine Nodes that correspond to the input Node (object of SDValue class).&lt;br /&gt;
&lt;br /&gt;
=== Selection DAG Node representation ===&lt;br /&gt;
LLVM uses mainly three classes to represent a SelectionDAG: '''SDNode''' and '''SDValue''' and '''SDUse'''. They are defined in &amp;quot;/compiler/include/llvm/CodeGen/SelectionDAGNodes.h&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''SDNode''' class is the representation of a ''node'' in the Selection DAG and stores information about the operation type and its operands (list of SDUse objects). &lt;br /&gt;
The '''SDValue''' represents the output value of a SDNode. However, a SDNode may return muiltiple valuesas the result of a computation. Thus the SDValue stores informations about the SDNode as well as which return value to use from that node.&lt;br /&gt;
The '''SDUse''' class represents a a use of a SDNode and holds an SDValue, which records the SDNode being used and the result number, a pointer to the SDNode using the value, and Next and Prev pointers, which link together all the uses of an SDNode.&lt;br /&gt;
&lt;br /&gt;
From a visual point of view, we can imagine a Selection DAG as composed by nodes and and edges. &lt;br /&gt;
A node has an operand list, an operation, an ID (all of them stored in a SDNode object) and one or more output values (each one represented by a SDValue object). &lt;br /&gt;
An arrow goes from an input operand to a return value (informations stored in a a SDUse object) and represents data flow among nodes. There are also &amp;quot;chain&amp;quot; edges that represent control flow and provide an ordering between nodes that have side effects such as loads, stores, calls, returns, etc.&lt;br /&gt;
&lt;br /&gt;
It is possible to visualize, during a compilation, the DAGs LLVM generates by passing the flag &amp;quot;-mllvm -debug=isel&amp;quot; (textual form) or using the &amp;quot;-view*&amp;quot; options (visual form). Note that LLVM must be compiled in &amp;quot;Debug&amp;quot; mode in order to show such informations.&lt;br /&gt;
&lt;br /&gt;
=== Lowering ===&lt;br /&gt;
The purpose of a custom lowering node function is to substitute the input node with a '''legal''' node or DAG that performs the same operation. The difference among a &amp;quot;legal&amp;quot; DAG and an &amp;quot;illegal&amp;quot; one, is that the legal DAG uses only operations an types supported by the machine. &lt;br /&gt;
&lt;br /&gt;
For example lets analyze &amp;quot;LowerFNEG&amp;quot; function. It is used to lower the FNEG node using legal nodes. &lt;br /&gt;
The FNEG operation must perform the negation of a floating-point value (see &amp;quot;/compiler/include/llvm/CodeGen/ISDOpcodes.h&amp;quot; for definition). Since the nu+ architecture does not have an instruction to directly perform the operation, we have to perform the lowering manually.&lt;br /&gt;
&lt;br /&gt;
The first step is to declare in the NuPlusTargetLowering class constructor that the FNEG operation must be custom lowered for all the supported floating-point types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
  // Note that this is just an example code. In nu+ backed &lt;br /&gt;
  // we use for loops to make the file more readable.&lt;br /&gt;
  setOperationAction(ISD::FNEG, MVT::f32, Custom);&lt;br /&gt;
  setOperationAction(ISD::FNEG, MVT::f64, Custom);&lt;br /&gt;
  setOperationAction(ISD::FNEG, MVT::v16f32, Custom);&lt;br /&gt;
  setOperationAction(ISD::FNEG, MVT::v8f64, Custom);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we update the switch in the &amp;quot;LowerOperation&amp;quot; function so that calls the &amp;quot;LowerFNEG&amp;quot; function, previously defined in the NuPlusTargetLowering&amp;quot; interface (located in &amp;quot;/compiler/lib/Target/NuPlus/NuPlusISelLowering.h&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
 SDValue NuPlusTargetLowering::LowerOperation(SDValue Op,&lt;br /&gt;
                                            SelectionDAG &amp;amp;DAG) const {&lt;br /&gt;
  ...&lt;br /&gt;
  case ISD::FNEG:&lt;br /&gt;
    return LowerFNEG(Op, DAG);&lt;br /&gt;
  ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
 class NuPlusTargetLowering : public TargetLowering {&lt;br /&gt;
  public:&lt;br /&gt;
   ...&lt;br /&gt;
   SDValue LowerFNEG(SDValue Op, SelectionDAG &amp;amp;DAG) const;&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then we define the &amp;quot;LowerFNEG&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
SDValue NuPlusTargetLowering::LowerFNEG(SDValue Op, SelectionDAG &amp;amp;DAG) const {&lt;br /&gt;
  SDLoc DL(Op);&lt;br /&gt;
  MVT ResultVT = Op.getValueType().getSimpleVT();&lt;br /&gt;
  MVT IntermediateVT;&lt;br /&gt;
&lt;br /&gt;
  if (ResultVT.isVector()) {&lt;br /&gt;
    IntermediateVT = &lt;br /&gt;
            (ResultVT.getVectorElementType() == MVT::f32) ? MVT::v16i32 : MVT::v8i64;&lt;br /&gt;
  } else {&lt;br /&gt;
    IntermediateVT = &lt;br /&gt;
            (ResultVT.getScalarType() == MVT::f32) ? MVT::i32 : MVT::i64;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  SDValue rhs = (IntermediateVT.getScalarType() == MVT::i32)   ? &lt;br /&gt;
                DAG.getConstant(0x80000000, DL, MVT::i32) :&lt;br /&gt;
                DAG.getConstant(0x8000000000000000, DL, MVT::i64);&lt;br /&gt;
                &lt;br /&gt;
  SDValue iconv;&lt;br /&gt;
  if (ResultVT.isVector())&lt;br /&gt;
    rhs = DAG.getNode(NuPlusISD::SPLAT, DL, IntermediateVT, rhs);&lt;br /&gt;
&lt;br /&gt;
  iconv = DAG.getNode(ISD::BITCAST, DL, IntermediateVT, Op.getOperand(0));&lt;br /&gt;
  SDValue flipped = DAG.getNode(ISD::XOR, DL, IntermediateVT, iconv, rhs);&lt;br /&gt;
  return DAG.getNode(ISD::BITCAST, DL, ResultVT, flipped);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The two inputs are &amp;quot;SDValue Op&amp;quot; and &amp;quot;SelectionDAG &amp;amp;DAG&amp;quot;. '''Op''' is the node that must be lowered, in this case an FNEG operation. It is a SDValue object because in this way we have also information about the output value. '''DAG''' is used to create the nodes containing the operations the one contained in '''Op'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:FNEGScalar.png|frame|This image shows how  the FNEG is lowered in case of scalar floating-point value.]]&lt;br /&gt;
[[File:FNEGVector.png|frame|This image shows how  the FNEG is lowered in case of vector floating-point value. Differently from the scalar case, the SPLAT node is added before the XOR.]]&lt;br /&gt;
&lt;br /&gt;
The function must return the last of the legal nodes generated. The figures belove show lowering of FNEG node.&lt;br /&gt;
&lt;br /&gt;
According to the IEEE 754 standard the MSB is the sign bit, thus to negate a floating-point value the MSB must be inverted. This could be done by XORing the floating-point value with 0x80000000 (for 32-bit floating-point) or 0x8000000000000000 (for 64-bit floating-point).&lt;br /&gt;
The XOR operation, however, can only be done between integer operations. Thus floating-point operand must be bitcasted into an integer before XORing it. The bitcast operation tells LLVM to interpret a value with a different type with same width (e.g. i32 &amp;lt;-&amp;gt; f32). The inverse bistacst operation need to be done also for the XOR return value that must be interpreted as a floating-point.&lt;br /&gt;
&lt;br /&gt;
In case of the FNEG is done on a vector type, we must add another node to correctly load the constant 0x80000000 (or 0x8000000000000000). This is done through the SPLAT operation. This operation takes a scalar and copies it on all the vector elements. In hardware it corresponds to a move operation.&lt;br /&gt;
&lt;br /&gt;
The function code first checks the result type, in order to determine the appropriate integer type for the constant and XOR operation (It is stored in the &amp;quot;IntermediateVT&amp;quot; variable).&lt;br /&gt;
Then we use the &amp;quot;getConstant&amp;quot; method to generate the Constant Node. The method takes the constant value, a SDLoc object containing the '''Op''' IR location info and the value type.&lt;br /&gt;
&lt;br /&gt;
If the input operand type is a vector, we generate a SPLAT node. &lt;br /&gt;
Then we create the XOR node preceded and succeeded by the SPLAT operations.&lt;br /&gt;
&lt;br /&gt;
The method &amp;quot;getNode&amp;quot; is used to generate nodes. It takes the node Opcode, the SDLoc object, the output value type and the input operands. The function returns only the SDValue of the last BITCAST operation since it stores the informations about the previous nodes.&lt;br /&gt;
&lt;br /&gt;
The SPLAT node does not belong to the &amp;quot;ISD&amp;quot; namespace but to the &amp;quot;NuPlusISD&amp;quot; namespace. This because LLVM does not have this node type and is defined only in the nu+ back-end. It will be resolved later during the Select phase using one of the patterns defined in [[NuPlusInstrInfo.td]].&lt;br /&gt;
&lt;br /&gt;
The other lowering functions act in a similar way. They lower the input node using the SelectionDAG class methods according to the operation to implement and the input node informations. &lt;br /&gt;
However, there are cases in which nodes tagged to be custom lowered are simply expanded. This is done, for example, in the &amp;quot;LowerBUILD_VECTOR&amp;quot; function in which the BUILD_VECTOR node must be lowered with a SPLAT operation only if the vector it tries to build is composed by the same scalar value, otherwise the expansion of the BUILD_VECTOR node is sufficient. &lt;br /&gt;
&lt;br /&gt;
The way to tell the Code Generator that the node must be expanded is to return an empty SDValue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
SDValue NuPlusTargetLowering::LowerBUILD_VECTOR(SDValue Op,&lt;br /&gt;
                                               SelectionDAG &amp;amp;DAG) const {&lt;br /&gt;
 // MVT VT = Op.getValueType().getSimpleVT();&lt;br /&gt;
  SDLoc DL(Op);&lt;br /&gt;
&lt;br /&gt;
  if (isSplatVector(Op.getNode())) {&lt;br /&gt;
    // This is a constant node that is duplicated to all lanes.&lt;br /&gt;
    // Convert it to a SPLAT node.&lt;br /&gt;
    return CheckSplat(Op, Op.getOperand(0), DAG);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return SDValue(); // Expand&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Custom MachineInstruction Insertion ==&lt;br /&gt;
&lt;br /&gt;
Another way to lower unsupported operations is to manually emit Machine Instructions. The emission of Machine Instructions takes place just before the '''Register Allocation'''. It is important to remember that the Machine Instructions are still in SSA form, so care must be taken when creating virtual registers.&lt;br /&gt;
&lt;br /&gt;
To instruct LLVM about what operations must have a custom inserter, a (pseudo)instruction in [[NuPlusInstrInfo.td]] with the '''usesCustomInserter''' flag setted to 1 must be defined.&lt;br /&gt;
&lt;br /&gt;
When an MachineInstruction must be custom inserted, LLVM calls the '''EmitInstrWithCustomInserter''' function passing it the Machine Instruction to lower and the Basic Block, the instruction belongs:&lt;br /&gt;
*The '''EmitInstrWithCustomInserter''' function is implemented with a switch on the Machine Instruction Opcode, according to its value returns the modified input basic block.&lt;br /&gt;
*The operand specific functions are named as ''EmitOPERATION_NAME'' and they must generate the instructions that correspond to the input Machine Instruction.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Insertion ===&lt;br /&gt;
The purpose of a custom instruction inserter function is to substitute the input Machine Instruction with instructions that perform the same operation.&lt;br /&gt;
&lt;br /&gt;
For example, lets consider the &amp;quot;EmitLoadI32&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
In nu+, the immediate field of type I instruction is 16 bits wide so to load a 32-bit immediate value the instruction couple MOVEIH-MOVEIL must be emitted.&lt;br /&gt;
&lt;br /&gt;
The EmitLoadI32 function is called by the EmitInstrWithCustomInserter hook function. The latter is called when the Code Generator encounters a machine instruction which has the usesCustomInserter flag setted to 1.&lt;br /&gt;
&lt;br /&gt;
Therefore, in NuPlusInstrInfo.td, the pseudo-instruction '''LoadI32''' is defined with usesCustomInserter = 1. The corresponding node is generated during the Select phase, when the pattern &amp;quot;(set i32:$dst, (i32 imm:$val))&amp;quot; is detected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def LoadI32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$val),&lt;br /&gt;
    [(set i32:$dst, (i32 imm:$val))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When must emit the instruction corresponding to '''LoadI32''', the &amp;quot;EmitLoadI32&amp;quot; is called (through the EmitInstrWithCustomInserter hook function). &lt;br /&gt;
The emit functions have at least two inputs ([http://llvm.org/docs/CodeGenerator.html#the-machineinstr-class MachineInstr] *MI and [http://llvm.org/docs/CodeGenerator.html#the-machinebasicblock-class MachineBasicBlock] *BB) and must return the MachineBasicBlock modified.&lt;br /&gt;
&lt;br /&gt;
To emit instructions the '''BuildMI''' interface (defined in &amp;quot;/compiler/include/llvm/CodeGen/MachineInstrBuilder.h&amp;quot;) is used. This interface allows a simple way to generate instructions, providing methods like addReg, addImm and etc.&lt;br /&gt;
&lt;br /&gt;
In the case of the EmitLoadI32, first the immediate values is taken from the LoadI32 operation, then the InsertLoad32Immediate function is called. This function is responsible of generating the MOVEIH-MOVEIL instruction couple. At last LoadI32 is deleted and the resulting Basic Block is returned.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
MachineBasicBlock *&lt;br /&gt;
NuPlusTargetLowering::EmitLoadI32(MachineInstr *MI,&lt;br /&gt;
                                  MachineBasicBlock *BB) const {&lt;br /&gt;
&lt;br /&gt;
  DebugLoc DL = MI-&amp;gt;getDebugLoc();&lt;br /&gt;
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();&lt;br /&gt;
  &lt;br /&gt;
  // Get the integer immediate value.&lt;br /&gt;
  int64_t ImmOp = MI-&amp;gt;getOperand(1).getImm();&lt;br /&gt;
  // Call the fuction that generates the MIs.&lt;br /&gt;
  InsertLoad32Immediate(MI, BB, TII, &amp;amp;DL, MI-&amp;gt;getOperand(0).getReg(), ImmOp);&lt;br /&gt;
&lt;br /&gt;
  MI-&amp;gt;eraseFromParent();&lt;br /&gt;
&lt;br /&gt;
  return BB;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The InsertLoad32Immediate function uses the BuildMI interface to generate the instructions. There are several versions of BuildMI, the one used takes as inputs the MachineBasicBlock where to insert the instructions, the pointer to the MachineInstruction before which insert the new instruction, a DebugLoc and the instruction description (MCInstrDesc class object) it must generate.&lt;br /&gt;
The instruction description is obtained through the TargetInstrInfo get method passing it the instruction name. &lt;br /&gt;
&lt;br /&gt;
Note: in a Machine Instruction the first operand is the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line='line'&amp;gt;&lt;br /&gt;
void InsertLoad32Immediate (MachineInstr *MI, MachineBasicBlock *BB,&lt;br /&gt;
                            const TargetInstrInfo *TII, DebugLoc *DL,&lt;br /&gt;
                            unsigned DestReg, int64_t Immediate) {&lt;br /&gt;
&lt;br /&gt;
  BuildMI(*BB, *MI, *DL, TII-&amp;gt;get(NuPlus::MOVEIHSI))&lt;br /&gt;
              .addReg(DestReg, RegState::Define)&lt;br /&gt;
              .addImm(((Immediate &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF));&lt;br /&gt;
  BuildMI(*BB, *MI, *DL, TII-&amp;gt;get(NuPlus::MOVEILSI))&lt;br /&gt;
              .addReg(DestReg)&lt;br /&gt;
              .addImm((Immediate &amp;amp; 0xFFFF));&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the instruction are still in SSA form, the code above shows a workaround to use the same destination register. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Methods ==&lt;br /&gt;
&lt;br /&gt;
The NuPlusTargetLowering class redefines also some other methods used to instruct the Code Generator about the specific capabilities supported or unsupported by the nu+ architecture.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusISelLowering.cpp&amp;diff=2116</id>
		<title>NuPlusISelLowering.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusISelLowering.cpp&amp;diff=2116"/>
				<updated>2019-06-21T14:43:32Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusISelLowering.cpp to NaplesPUISelLowering.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUISelLowering.cpp]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUInstrFormats.td&amp;diff=2113</id>
		<title>NaplesPUInstrFormats.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUInstrFormats.td&amp;diff=2113"/>
				<updated>2019-06-21T14:42:50Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusInstrFormats.td to NaplesPUInstrFormats.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
The NuPlusInstrFormats.td contains the classes that describe the [[ISA|nu+ instruction formats]], support classes to facilitate the instructions definition and also the definition nodes which make the pattern recognition easier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusInstrFormats.td - NuPlus Instruction Formats ---*- tablegen -*-===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Instruction Pattern Stuff&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def simm16  : PatLeaf&amp;lt;(imm), [{ return isInt&amp;lt;16&amp;gt;(N-&amp;gt;getSExtValue()); }]&amp;gt;;&lt;br /&gt;
def simm9  : PatLeaf&amp;lt;(imm), [{ return isInt&amp;lt;9&amp;gt;(N-&amp;gt;getSExtValue()); }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Addressing modes as in SPARC&lt;br /&gt;
def ADDRri : ComplexPattern&amp;lt;iPTR, 2, &amp;quot;SelectADDRri&amp;quot;, [frameindex], []&amp;gt;;&lt;br /&gt;
def V16ADDRri : ComplexPattern&amp;lt;v16i32, 2, &amp;quot;SelectADDRri&amp;quot;, [], []&amp;gt;;&lt;br /&gt;
def V8ADDRri : ComplexPattern&amp;lt;v8i64, 2, &amp;quot;SelectADDRri&amp;quot;, [], []&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// NuPlus profiles and nodes&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Transformation nodes&lt;br /&gt;
def LO32I : SDNodeXForm&amp;lt;imm, [{&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)N-&amp;gt;getAPIntValue().getLoBits(32).getZExtValue(), SDLoc(N), MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def HI32I : SDNodeXForm&amp;lt;imm, [{&lt;br /&gt;
  // Transformation function: shift the immediate value down into the low bits.&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)N-&amp;gt;getAPIntValue().getHiBits(32).getZExtValue(), SDLoc(N),  MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def LO32F : SDNodeXForm&amp;lt;fpimm, [{&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)(N-&amp;gt;getValueAPF().bitcastToAPInt().getLoBits(32).getZExtValue()), SDLoc(N), MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def HI32F : SDNodeXForm&amp;lt;fpimm, [{&lt;br /&gt;
  // Transformation function: shift the immediate value down into the low bits.&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)(N-&amp;gt;getValueAPF().bitcastToAPInt().getHiBits(32).getZExtValue()), SDLoc(N),  MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def DIV2 : SDNodeXForm&amp;lt;imm, [{&lt;br /&gt;
  return CurDAG-&amp;gt;getTargetConstant((unsigned)N-&amp;gt;getZExtValue() / 2, SDLoc(N), MVT::i32);}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// Moveil/moveih nodes definition, used for globaladdress lowering&lt;br /&gt;
def leah  : SDNode&amp;lt;&amp;quot;NuPlusISD::LEAH&amp;quot;, SDTypeProfile&amp;lt;1, 1, []&amp;gt;&amp;gt;;&lt;br /&gt;
def leal  : SDNode&amp;lt;&amp;quot;NuPlusISD::LEAL&amp;quot;, SDTypeProfile&amp;lt;1, 2, []&amp;gt;&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
// A splat is a vector with the same value in all lanes. Used to handle operation&lt;br /&gt;
// with both vector and scalar operands.&lt;br /&gt;
def splat : SDNode&amp;lt;&amp;quot;NuPlusISD::SPLAT&amp;quot;, SDTypeProfile&amp;lt;1, 1, [SDTCisEltOfVec&amp;lt;1, 0&amp;gt;]&amp;gt;&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def return : SDNode&amp;lt;&amp;quot;NuPlusISD::RET_FLAG&amp;quot;, SDTypeProfile&amp;lt;0, 0, []&amp;gt;, &lt;br /&gt;
	[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def SDT_SPCall : SDTypeProfile&amp;lt;0, -1, [SDTCisVT&amp;lt;0, i32&amp;gt;]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def call : SDNode&amp;lt;&amp;quot;NuPlusISD::CALL&amp;quot;, SDT_SPCall, &lt;br /&gt;
	[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//To mark the beginning and end of a call sequence&lt;br /&gt;
def SDT_SPCallSeqStart : SDCallSeqStart&amp;lt;[SDTCisVT&amp;lt;0, i32&amp;gt;, SDTCisVT&amp;lt;1, i32&amp;gt;]&amp;gt;;&lt;br /&gt;
 def SDT_SPCallSeqEnd : SDCallSeqEnd&amp;lt;[SDTCisVT&amp;lt;0, i32&amp;gt;, SDTCisVT&amp;lt;1, i32&amp;gt;]&amp;gt;;&lt;br /&gt;
 def callseq_start : SDNode&amp;lt;&amp;quot;ISD::CALLSEQ_START&amp;quot;, SDT_SPCallSeqStart,&lt;br /&gt;
                            [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]&amp;gt;;&lt;br /&gt;
 def callseq_end : SDNode&amp;lt;&amp;quot;ISD::CALLSEQ_END&amp;quot;, SDT_SPCallSeqEnd,&lt;br /&gt;
                            [SDNPHasChain, SDNPSideEffect,&lt;br /&gt;
                             SDNPOptInGlue, SDNPOutGlue]&amp;gt;; &lt;br /&gt;
//To handle the lack of conditional moves&lt;br /&gt;
def selcondresult : SDNode&amp;lt;&amp;quot;NuPlusISD::SEL_COND_RESULT&amp;quot;, SDTypeProfile&amp;lt;1, 3, &lt;br /&gt;
							[SDTCisSameAs&amp;lt;0, 2&amp;gt;, SDTCisSameAs&amp;lt;0, 3&amp;gt;]&amp;gt;&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Operand Definitions&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// Used for the LEA_Sym, to detect the lea pseudo instruction&lt;br /&gt;
def symref : Operand&amp;lt;OtherVT&amp;gt; {}&lt;br /&gt;
&lt;br /&gt;
def SIMM16OP : Operand&amp;lt;i32&amp;gt; {&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeSimm16Value&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def SIMM9OP : Operand&amp;lt;i32&amp;gt; {&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeSimm9Value&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def MemAsmOperand : AsmOperandClass {&lt;br /&gt;
  let Name = &amp;quot;Mem&amp;quot;;&lt;br /&gt;
  let ParserMethod = &amp;quot;ParseMemoryOperand&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def MEMri : Operand&amp;lt;iPTR&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeMemoryOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeScalarMemoryOpValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand;&lt;br /&gt;
  let MIOperandInfo = (ops GPR32, i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def V16MEMri : Operand&amp;lt;v16i32&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeMemoryOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeVectorWMemoryOpValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand;&lt;br /&gt;
  let MIOperandInfo = (ops VR512W, i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def LEAri : Operand&amp;lt;iPTR&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeLEAValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass&lt;br /&gt;
  let MIOperandInfo = (ops GPR32, i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def ABSh : Operand&amp;lt;iPTR&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeABShValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass&lt;br /&gt;
  let MIOperandInfo = (ops i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def ABSl : Operand&amp;lt;iPTR&amp;gt; {&lt;br /&gt;
  let PrintMethod = &amp;quot;printMemOperand&amp;quot;;&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeABSlValue&amp;quot;;&lt;br /&gt;
  let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass&lt;br /&gt;
  let MIOperandInfo = (ops i32imm);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def brtarget : Operand&amp;lt;OtherVT&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeBranchTargetOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeBranchTargetOpValue&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def calltarget : Operand&amp;lt;iPTR&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  let EncoderMethod = &amp;quot;encodeBranchTargetOpValue&amp;quot;;&lt;br /&gt;
  let DecoderMethod = &amp;quot;decodeBranchTargetOpValue&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Pattern fragments&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Definition of anyextload used in the loading of vector types &amp;lt; 512 bits&lt;br /&gt;
def anyextload : PatFrag&amp;lt;(ops node:$ptr), (unindexedload node:$ptr), &lt;br /&gt;
    [{ return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getExtensionType() != ISD::NON_EXTLOAD;}]&amp;gt;; &lt;br /&gt;
&lt;br /&gt;
//----------------------------------------------------------------------------// &lt;br /&gt;
//------------------------------ LOAD AND STORE ------------------------------// &lt;br /&gt;
//----------------------------------------------------------------------------// &lt;br /&gt;
&lt;br /&gt;
def MemStore : PatFrag&amp;lt;(ops node:$val, node:$ptr), (store node:$val, node:$ptr), [{&lt;br /&gt;
                            if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
                              return !cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;isTruncatingStore();&lt;br /&gt;
                            else&lt;br /&gt;
                              return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def MemLoad : PatFrag&amp;lt;(ops node:$ptr), (load node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getExtensionType() == ISD::NON_EXTLOAD;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def ScratchpadStore : PatFrag&amp;lt;(ops node:$val, node:$ptr), (store node:$val, node:$ptr), [{&lt;br /&gt;
                            if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
                              return !cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;isTruncatingStore();&lt;br /&gt;
                            else&lt;br /&gt;
                              return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def ScratchpadLoad : PatFrag&amp;lt;(ops node:$ptr), (load node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getExtensionType() == ISD::NON_EXTLOAD;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- EXTLOAD scalar ----------------// &lt;br /&gt;
def extloadi1_mem : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def extloadi1_scratch : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def extloadi8_mem : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def extloadi8_scratch : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def extloadi16_mem : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def extloadi16_scratch : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def extloadi32_mem : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def extloadi32_scratch : PatFrag&amp;lt;(ops node:$ptr), (extload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- ZEXTLOAD scalar ----------------// &lt;br /&gt;
def zextloadi1_mem : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def zextloadi1_scratch : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadi8_mem : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def zextloadi8_scratch : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadi16_mem : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def zextloadi16_scratch : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadi32_mem : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def zextloadi32_scratch : PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- ZEXTLOAD vector ----------------// &lt;br /&gt;
def zextloadv16i8_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv16i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadv16i16_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv16i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadv8i8_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv8i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadv8i16_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv8i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def zextloadv8i32_mem: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def zextloadv8i32_scratch: PatFrag&amp;lt;(ops node:$ptr), (zextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;                  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//---------------- SEXTLOAD scalar ----------------// &lt;br /&gt;
def sextloadi1_mem : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def sextloadi1_scratch : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadi8_mem : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def sextloadi8_scratch : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadi16_mem : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def sextloadi16_scratch : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadi32_mem : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def sextloadi32_scratch : PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
			&lt;br /&gt;
//---------------- SEXTLOAD vector ----------------// &lt;br /&gt;
def sextloadv16i8_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv16i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadv16i16_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv16i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadv8i8_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv8i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadv8i16_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv8i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def sextloadv8i32_mem: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def sextloadv8i32_scratch: PatFrag&amp;lt;(ops node:$ptr), (sextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;                                    &lt;br /&gt;
&lt;br /&gt;
		 			&lt;br /&gt;
//---------------- ANYEXTLOAD vector ----------------// &lt;br /&gt;
def anyextloadv16i8_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr), &lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv16i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr), &lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def anyextloadv16i16_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv16i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def anyextloadv8i8_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv8i8_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;         &lt;br /&gt;
&lt;br /&gt;
def anyextloadv8i16_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv8i16_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def anyextloadv8i32_mem: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
        return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
      else&lt;br /&gt;
        return false; }]&amp;gt;;&lt;br /&gt;
def anyextloadv8i32_scratch: PatFrag&amp;lt;(ops node:$ptr), (anyextload node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
         return cast&amp;lt;LoadSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
       else&lt;br /&gt;
         return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		 &lt;br /&gt;
//---------------- TRUNCSTORE scalar ----------------// &lt;br /&gt;
def truncstorei1_mem : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def truncstorei1_scratch : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i1;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorei8_mem : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def truncstorei8_scratch : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorei16_mem : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def truncstorei16_scratch : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorei32_mem : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
def truncstorei32_scratch : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                           (truncstore node:$val, node:$ptr), [{&lt;br /&gt;
          if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false;}]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//---------------- TRUNCSTORE vector ----------------// &lt;br /&gt;
def truncstorev16i8_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev16i8_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;   &lt;br /&gt;
&lt;br /&gt;
def truncstorev16i16_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev16i16_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v16i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorev8i8_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev8i8_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i8;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorev8i16_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev8i16_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i16;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def truncstorev8i32_mem: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;&lt;br /&gt;
def truncstorev8i32_scratch: PatFrag&amp;lt;(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),&lt;br /&gt;
    [{ if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
            return cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getMemoryVT() == MVT::v8i32;&lt;br /&gt;
          else&lt;br /&gt;
            return false; }]&amp;gt;;                                                         &lt;br /&gt;
&lt;br /&gt;
			&lt;br /&gt;
// insertelt SDNode redefinition&lt;br /&gt;
def VecInsert : SDTypeProfile&amp;lt;1, 3, [    // vector insert&lt;br /&gt;
   SDTCisSameAs&amp;lt;0, 1&amp;gt;, SDTCisPtrTy&amp;lt;3&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def insert_elt  : SDNode&amp;lt;&amp;quot;ISD::INSERT_VECTOR_ELT&amp;quot;, VecInsert&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Describe NuPlus Special Registers&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class SpReg&amp;lt;bits&amp;lt;6&amp;gt; reg&amp;gt; {&lt;br /&gt;
  bits&amp;lt;6&amp;gt; Register = reg;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def MaskReg : SpReg&amp;lt;59&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Describe NuPlus scalar or vector instructions&lt;br /&gt;
//&lt;br /&gt;
//  Fmt   - 0 if a register is scalar, 1 if vector&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class Fmt&amp;lt;bit val&amp;gt; {&lt;br /&gt;
  bit Value = val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def Fmt_S : Fmt&amp;lt;0&amp;gt;;&lt;br /&gt;
def Fmt_V : Fmt&amp;lt;1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Describe NuPlus instructions format here&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class InstNuPlus&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern&amp;gt;&lt;br /&gt;
          : Instruction {&lt;br /&gt;
  field bits&amp;lt;32&amp;gt; Inst;&lt;br /&gt;
&lt;br /&gt;
  let Namespace = &amp;quot;NuPlus&amp;quot;;&lt;br /&gt;
  let Size = 4;&lt;br /&gt;
&lt;br /&gt;
  dag OutOperandList = outs;&lt;br /&gt;
  dag InOperandList = ins;&lt;br /&gt;
  let AsmString   = asmstr;&lt;br /&gt;
  let Pattern = pattern;&lt;br /&gt;
&lt;br /&gt;
  //let DecoderNamespace = &amp;quot;NuPlus&amp;quot;;&lt;br /&gt;
  field bits&amp;lt;32&amp;gt; SoftFail = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format R instruction class in NuPlus : &amp;lt;00|opcode|rd|rs0|rs1|unused|l|fmt|m|&amp;gt;&lt;br /&gt;
// l: if 1, 64 bit mode&lt;br /&gt;
// fmt2: FMT value for rd register&lt;br /&gt;
// fmt1: FMT value for rs0 register&lt;br /&gt;
// fmt0: FMT value for rs1 register&lt;br /&gt;
// m: if 1, masked&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FR&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m&amp;gt;&lt;br /&gt;
   : InstNuPlus&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dst;&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src0;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-30} = 0;&lt;br /&gt;
  let Inst{29-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-12} = src0;&lt;br /&gt;
  let Inst{5} = 0; //unused&lt;br /&gt;
  let Inst{4} = l;&lt;br /&gt;
  let Inst{3} = fmt2.Value;&lt;br /&gt;
  let Inst{2} = fmt1.Value;&lt;br /&gt;
  let Inst{1} = fmt0.Value;&lt;br /&gt;
  let Inst{0} = m;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m&amp;gt;&lt;br /&gt;
   : FR&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, m&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src1;&lt;br /&gt;
&lt;br /&gt;
  let Inst{11-6} = src1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m&amp;gt;&lt;br /&gt;
   : FR&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, m&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  let Inst{11-6} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Masked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, 1&amp;gt; {&lt;br /&gt;
  let Uses = [MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Unmasked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, 0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Masked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, Fmt_S, 1&amp;gt; {&lt;br /&gt;
  let Uses = [MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Unmasked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp&amp;lt;outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, Fmt_S, 0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Masked_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Masked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Unmasked_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp_Unmasked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Masked_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Masked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Unmasked_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp_Unmasked_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1&amp;gt;&lt;br /&gt;
   : FR_OneOp_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format I instruction class in NuPlus : &amp;lt;010|opcode|rd|rs|imm|fmt|m|&amp;gt;&lt;br /&gt;
// fmt1: FMT value for rd register&lt;br /&gt;
// fmt0: FMT value for rs register&lt;br /&gt;
// m: if 1 masked&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FI&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1, Fmt fmt0, bit m&amp;gt;&lt;br /&gt;
    : InstNuPlus&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dst;&lt;br /&gt;
  bits &amp;lt;9&amp;gt; imm;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-29} = 0b010;&lt;br /&gt;
  let Inst{28-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{11-3} = imm;&lt;br /&gt;
  let Inst{2} = fmt1.Value;&lt;br /&gt;
  let Inst{1} = fmt0.Value;&lt;br /&gt;
  let Inst{0} = m;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FI_OneOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1, Fmt fmt0, bit m&amp;gt; : FI&amp;lt;outs, ins, asmstr, pattern, opcode, fmt1, fmt0, m&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src;&lt;br /&gt;
&lt;br /&gt;
  let Inst{17-12} = src;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FI_NoOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1&amp;gt; : FI&amp;lt;outs, ins, asmstr, pattern, opcode, fmt1, Fmt_S, 0&amp;gt; {&lt;br /&gt;
  let Inst{17-12} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FI_OneOp_Masked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1, Fmt fmt0&amp;gt; : FI_OneOp&amp;lt;outs, ins, asmstr, pattern, opcode, fmt1, fmt0, 1&amp;gt; {&lt;br /&gt;
  let Uses = [MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FI_OneOp_Unmasked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;5&amp;gt; opcode, Fmt fmt1, Fmt fmt0&amp;gt; : FI_OneOp&amp;lt;outs, ins, asmstr, pattern, opcode, fmt1, fmt0, 0&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format MOVEI instruction class in NuPlus : &amp;lt;01100|opcode|rd|imm|fmt|m|&amp;gt;&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FMOVEI&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode, Fmt fmt, bit m&amp;gt;&lt;br /&gt;
      : InstNuPlus&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dst;&lt;br /&gt;
  bits &amp;lt;16&amp;gt; imm;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-27} = 0b01100;&lt;br /&gt;
  let Inst{26-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-2} = imm;&lt;br /&gt;
  let Inst{1} = fmt.Value;&lt;br /&gt;
  let Inst{0} = m;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format M instruction class in NuPlus : &amp;lt;10|opcode|rd/rs|rptr|off|l|s|m|&amp;gt;&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FM&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, bit s, bit m&amp;gt;&lt;br /&gt;
    : InstNuPlus&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dstsrc;&lt;br /&gt;
  bits &amp;lt;15&amp;gt; addr; //base address and offset encoded on the same 15 bits value (check encodeMemoryOpValue)&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-30} = 0b10;&lt;br /&gt;
  let Inst{29-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dstsrc;&lt;br /&gt;
  let Inst{17-12} = addr{5-0};&lt;br /&gt;
  let Inst{11-3} = addr{14-6};&lt;br /&gt;
  let Inst{2} = l;&lt;br /&gt;
  let Inst{1} = s;&lt;br /&gt;
  let Inst{0} = m;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, bit s&amp;gt;&lt;br /&gt;
   : FM&amp;lt;outs, ins, asmstr, pattern, opcode, l, s, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l, bit s&amp;gt;&lt;br /&gt;
   : FM&amp;lt;outs, ins, asmstr, pattern, opcode, l, s, 1&amp;gt; {&lt;br /&gt;
  let Uses = [MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Mainmem&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l&amp;gt;&lt;br /&gt;
   : FM_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, l, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Scratchpad&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l&amp;gt;&lt;br /&gt;
   : FM_Unmasked&amp;lt;outs, ins, asmstr, pattern, opcode, l, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Mainmem&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l&amp;gt;&lt;br /&gt;
   : FM_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, l, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Scratchpad&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, bit l&amp;gt;&lt;br /&gt;
   : FM_Masked&amp;lt;outs, ins, asmstr, pattern, opcode, l, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Mainmem_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Unmasked_Mainmem&amp;lt;outs, ins, asmstr, pattern, opcode, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Scratchpad_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Unmasked_Scratchpad&amp;lt;outs, ins, asmstr, pattern, opcode, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Mainmem_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Masked_Mainmem&amp;lt;outs, ins, asmstr, pattern, opcode, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Scratchpad_32&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Masked_Scratchpad&amp;lt;outs, ins, asmstr, pattern, opcode, 0&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Mainmem_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Unmasked_Mainmem&amp;lt;outs, ins, asmstr, pattern, opcode, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Unmasked_Scratchpad_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Unmasked_Scratchpad&amp;lt;outs, ins, asmstr, pattern, opcode, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Mainmem_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Masked_Mainmem&amp;lt;outs, ins, asmstr, pattern, opcode, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FM_Masked_Scratchpad_64&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode&amp;gt;&lt;br /&gt;
   : FM_Masked_Scratchpad&amp;lt;outs, ins, asmstr, pattern, opcode, 1&amp;gt; {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format J/BR instruction class in NuPlus &lt;br /&gt;
// FJR: &amp;lt;0111|type(0/1)|opcode|rd|imm|&amp;gt;&lt;br /&gt;
// FJ:  &amp;lt;0111|type(0/1)|opcode|imm|&amp;gt;&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FJ_ALL&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode&amp;gt;&lt;br /&gt;
    : InstNuPlus&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-28} = 0b0111;&lt;br /&gt;
  let Inst{26-24} = opcode;&lt;br /&gt;
  let isBranch = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FJR&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode&amp;gt;&lt;br /&gt;
    : FJ_ALL&amp;lt;outs, ins, asmstr, pattern, opcode&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; cond;&lt;br /&gt;
  bits &amp;lt;18&amp;gt; addr;&lt;br /&gt;
&lt;br /&gt;
  let Inst{27} = 0;&lt;br /&gt;
  let Inst{23-18} = cond;&lt;br /&gt;
  let Inst{17-0} = addr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FJ&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode&amp;gt;&lt;br /&gt;
    : FJ_ALL&amp;lt;outs, ins, asmstr, pattern, opcode&amp;gt; {&lt;br /&gt;
  bits &amp;lt;24&amp;gt; addr;&lt;br /&gt;
&lt;br /&gt;
  let Inst{27} = 1;&lt;br /&gt;
  let Inst{23-0} = addr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Format C instruction class in NuPlus &lt;br /&gt;
// FC:  &amp;lt;01101|opcode|rs0|rs1|unused|&amp;gt;&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
class FC&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;3&amp;gt; opcode&amp;gt;&lt;br /&gt;
    : InstNuPlus&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src0;&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src1;&lt;br /&gt;
&lt;br /&gt;
  let Inst{31-27} = 0b01101;&lt;br /&gt;
  let Inst{26-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = src0;&lt;br /&gt;
  let Inst{17-12} = src1;&lt;br /&gt;
  let Inst{11-0} = 0; //unused&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  A set of multiclasses is used to handle Vector/Scalar combinations&lt;br /&gt;
//   SS: Scalar = Op Scalar&lt;br /&gt;
//   VV: Vector = Op Vector&lt;br /&gt;
//   SI: Vector = Op Immediate&lt;br /&gt;
//  SSS: Scalar = Scalar Op Scalar&lt;br /&gt;
//  VVS: Vector = Vector Op Scalar&lt;br /&gt;
//  VVV: Vector = Vector Op Vector&lt;br /&gt;
//  SVV: Scalar = Vector Op Vector&lt;br /&gt;
//  SSI: Scalar = Vector Op Immediate&lt;br /&gt;
//  VVI: Scalar = Vector Op Immediate&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
multiclass FArithInt_TwoOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit integer&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src0, i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVS unmasked - 32 bit integer&lt;br /&gt;
  def VVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVV unmasked - 32 bit integer&lt;br /&gt;
  def VVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VVS masked - 32 bit integer&lt;br /&gt;
    def VVS_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // FR - VVV masked - 32 bit integer&lt;br /&gt;
    def VVV_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0, v16i32:$src1),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
  // FI - SSI&lt;br /&gt;
  def SSI : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src, (i32 simm9:$imm)))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - VVI unmasked&lt;br /&gt;
  def VVI_U : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - VVI masked&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    def VVI_M : FI_OneOp_Masked&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm, VR512W:$oldvalue),&lt;br /&gt;
    operator # &amp;quot;i.m $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))), v16i32:$oldvalue))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FArithInt_OneOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SS - 32 bit integer&lt;br /&gt;
  def SS_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VV unmasked - 32 bit integer&lt;br /&gt;
  def VV_U_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VV masked - 32 bit integer&lt;br /&gt;
    def VV_M_32 : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// per la shift rotate&lt;br /&gt;
multiclass FSRInt_TwoOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit integer&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src0, i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVS unmasked - 32 bit integer&lt;br /&gt;
  def VVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVV unmasked - 32 bit integer&lt;br /&gt;
  def VVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VVS masked - 32 bit integer&lt;br /&gt;
    def VVS_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // FR - VVV masked - 32 bit integer&lt;br /&gt;
    def VVV_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0, v16i32:$src1),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
  // FI - SSI&lt;br /&gt;
  def SSI : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src, (i32 simm9:$imm)))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - VVI unmasked&lt;br /&gt;
  def VVI_U : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - VVI masked&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    def VVI_M : FI_OneOp_Masked&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm, VR512W:$oldvalue),&lt;br /&gt;
    operator # &amp;quot;i.m $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))), v16i32:$oldvalue))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FArithFloat_TwoOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit float&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set f32:$dst, (OpNode f32:$src0, f32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVS unmasked - 32 bit float&lt;br /&gt;
  def VVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (OpNode v16f32:$src0, (splat f32:$src1)))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VVV unmasked - 32 bit float&lt;br /&gt;
  def VVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (OpNode v16f32:$src0, v16f32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VVS masked - 32 bit float&lt;br /&gt;
    def VVS_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),&lt;br /&gt;
    operator # &amp;quot;_f32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (int_nuplus_vector_mixf32 (OpNode v16f32:$src0, (splat f32:$src1)),&lt;br /&gt;
        v16f32:$oldvalue))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // FR - VVV masked - 32 bit float&lt;br /&gt;
    def VVV_M_32 : FR_TwoOp_Masked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),&lt;br /&gt;
    operator # &amp;quot;_f32.m $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (int_nuplus_vector_mixf32 (OpNode v16f32:$src0, v16f32:$src1),&lt;br /&gt;
        v16f32:$oldvalue))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FArithFloat_OneOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // FR - SS - 32 bit float&lt;br /&gt;
  def SS_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set f32:$dst, (OpNode f32:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VV unmasked - 32 bit float&lt;br /&gt;
  def VV_U_32 : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16f32:$dst, (OpNode v16f32:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VV masked - 32 bit float&lt;br /&gt;
    def VV_M_32 : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_f32.m $dst, $src0&amp;quot;,&lt;br /&gt;
      [(set v16f32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Condition codes defined in include/llvm/CodeGen/ISDOpcodes.h&lt;br /&gt;
// VS and VV comparisons are handled through intrinsics&lt;br /&gt;
multiclass FCompInt&amp;lt;string operator, CondCode condition,&lt;br /&gt;
  bits&amp;lt;6&amp;gt; opcode, Intrinsic vectorIntr32&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit integer&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (setcc i32:$src0, i32:$src1, condition))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - SVS unmasked - 32 bit integer&lt;br /&gt;
  def SVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16i32:$src0, (splat i32:$src1)))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - SVV unmasked - 32 bit integer&lt;br /&gt;
  def SVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16i32:$src0, v16i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - SSI&lt;br /&gt;
  def SSI : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (setcc i32:$src, simm9:$imm, condition))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FI - SVI unmasked&lt;br /&gt;
  def SVI : FI_OneOp_Unmasked&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src, SIMM9OP:$imm),&lt;br /&gt;
    operator # &amp;quot;i $dst, $src, $imm&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16i32:$src, (splat simm9:$imm)))],&lt;br /&gt;
    opcode{4-0},&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FCompFloat&amp;lt;string operator, SDNode OpNode,&lt;br /&gt;
  bits&amp;lt;6&amp;gt; opcode, Intrinsic vectorIntr32&amp;gt; {&lt;br /&gt;
  // FR - SSS - 32 bit float&lt;br /&gt;
  def SSS_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode f32:$src0, f32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - SVS unmasked - 32 bit float&lt;br /&gt;
  def SVS_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16f32:$src0, (splat f32:$src1)))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - SVV unmasked - 32 bit float&lt;br /&gt;
  def SVV_U_32 : FR_TwoOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins VR512W:$src0, VR512W:$src1),&lt;br /&gt;
    operator # &amp;quot;_f32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (vectorIntr32 v16f32:$src0, v16f32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass FSext_32&amp;lt;string operator, ValueType vt,&lt;br /&gt;
  bits&amp;lt;6&amp;gt; opcode, ValueType vt_v&amp;gt; {&lt;br /&gt;
  // FR - SS&lt;br /&gt;
  def SS : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (sext_inreg i32:$src0, vt))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // FR - VV unmasked&lt;br /&gt;
  def VV_U : FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins VR512W:$src0),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dst, (sext vt_v:$src0))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    Fmt_V&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  let Constraints = &amp;quot;$dst = $oldvalue&amp;quot; in {&lt;br /&gt;
    // FR - VV masked&lt;br /&gt;
    def VV_M : FR_OneOp_Masked_32&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins VR512W:$src0, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;_i32.m $dst, $src0&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_nuplus_vector_mixi32 (sext vt_v:$src0),&lt;br /&gt;
        v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      Fmt_V&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  A set of multiclasses used to handle Loads and Stores&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// Scalar LOAD&lt;br /&gt;
multiclass FMLoadScalar_32&amp;lt;string suffix, PatFrag op_mem, PatFrag op_scratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  def _Mainmem : FM_Unmasked_Mainmem&amp;lt;&lt;br /&gt;
    (outs GPR32:$dstsrc), &lt;br /&gt;
    (ins MEMri:$addr), &lt;br /&gt;
    &amp;quot;load32&amp;quot; # suffix # &amp;quot; $dstsrc, $addr&amp;quot;, &lt;br /&gt;
    [(set i32:$dstsrc, (i32 (op_mem ADDRri:$addr)))], &lt;br /&gt;
    opcode, &lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def _Scratchpad : FM_Unmasked_Scratchpad&amp;lt;&lt;br /&gt;
    (outs GPR32:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load32&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set i32:$dstsrc, (i32 (op_scratch ADDRri:$addr)))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Scalar STORE&lt;br /&gt;
multiclass FMStoreScalar_32&amp;lt;string suffix, PatFrag op_mem, PatFrag op_scratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  def _Mainmem : FM_Unmasked_Mainmem&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store32&amp;quot; # suffix # &amp;quot; $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_mem i32:$dstsrc, ADDRri:$addr)],&lt;br /&gt;
    opcode, &lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def _Scratchpad : FM_Unmasked_Scratchpad&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins GPR32:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store32&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_scratch i32:$dstsrc, ADDRri:$addr)],&lt;br /&gt;
    opcode,&lt;br /&gt;
    0&amp;gt;{&lt;br /&gt;
        let hasSideEffects = 1;&lt;br /&gt;
        let mayStore = 1;&lt;br /&gt;
      }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Vector LOAD&lt;br /&gt;
multiclass FMLoadVector_32&amp;lt;string suffix, PatFrag op_Umem, PatFrag op_Uscratch, &lt;br /&gt;
                           Intrinsic op_Mmem, Intrinsic op_Mscratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  // main memory - unmasked - 32&lt;br /&gt;
  def Mainmem_U : FM_Unmasked_Mainmem_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load&amp;quot; # suffix # &amp;quot; $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Umem ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // scratchpad memory - unmasked - 32&lt;br /&gt;
  def Scratchpad_U : FM_Unmasked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Uscratch ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // main memory - masked - 32&lt;br /&gt;
  def Mainmem_M : FM_Masked_Mainmem_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load&amp;quot; # suffix # &amp;quot;.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Mmem ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // scratchpad memory - masked - 32&lt;br /&gt;
  def Scratchpad_M : FM_Masked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins MEMri:$addr),&lt;br /&gt;
    &amp;quot;load&amp;quot; # suffix # &amp;quot;_scratchpad.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Mscratch ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Vector GATHER&lt;br /&gt;
multiclass FMGather_32&amp;lt;string suffix, Intrinsic op_Uscratch, &lt;br /&gt;
                           Intrinsic op_Mscratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  &lt;br /&gt;
  // scratchpad memory - unmasked - 32&lt;br /&gt;
  def Scratchpad_U : FM_Unmasked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins V16MEMri:$addr),&lt;br /&gt;
    &amp;quot;loadg&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Uscratch V16ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
  // scratchpad memory - masked - 32&lt;br /&gt;
  def Scratchpad_M : FM_Masked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs VR512W:$dstsrc),&lt;br /&gt;
    (ins V16MEMri:$addr),&lt;br /&gt;
    &amp;quot;loadg&amp;quot; # suffix # &amp;quot;_scratchpad.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(set v16i32:$dstsrc, (op_Mscratch V16ADDRri:$addr))],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Vector STORE&lt;br /&gt;
multiclass FMStoreVector_32&amp;lt;string suffix, PatFrag op_Umem, PatFrag op_Uscratch, &lt;br /&gt;
                           Intrinsic op_Mmem, Intrinsic op_Mscratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  // main memory - unmasked - 32&lt;br /&gt;
  def Mainmem_U : FM_Unmasked_Mainmem_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store&amp;quot; # suffix # &amp;quot; $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Umem v16i32:$dstsrc, ADDRri:$addr)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
  // scratchpad memory - unmasked - 32&lt;br /&gt;
  def Scratchpad_U : FM_Unmasked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Uscratch v16i32:$dstsrc, ADDRri:$addr)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
  // main memory - masked - 32&lt;br /&gt;
  def Mainmem_M : FM_Masked_Mainmem_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store&amp;quot; # suffix # &amp;quot;.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Mmem ADDRri:$addr, v16i32:$dstsrc)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
  // scratchpad memory - masked - 32&lt;br /&gt;
  def Scratchpad_M : FM_Masked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, MEMri:$addr),&lt;br /&gt;
    &amp;quot;store&amp;quot; # suffix # &amp;quot;_scratchpad.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Mscratch ADDRri:$addr, v16i32:$dstsrc)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Vector SCATTER&lt;br /&gt;
multiclass FMScatter_32&amp;lt;string suffix, Intrinsic op_Uscratch, &lt;br /&gt;
                           Intrinsic op_Mscratch, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
  // scratchpad memory - unmasked - 32&lt;br /&gt;
  def Scratchpad_U : FM_Unmasked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, V16MEMri:$addr),&lt;br /&gt;
    &amp;quot;stores&amp;quot; # suffix # &amp;quot;_scratchpad $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Uscratch V16ADDRri:$addr, v16i32:$dstsrc)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // scratchpad memory - masked - 32&lt;br /&gt;
  def Scratchpad_M : FM_Masked_Scratchpad_32&amp;lt;&lt;br /&gt;
    (outs),&lt;br /&gt;
    (ins VR512W:$dstsrc, V16MEMri:$addr),&lt;br /&gt;
    &amp;quot;stores&amp;quot; # suffix # &amp;quot;_scratchpad.m $dstsrc, $addr&amp;quot;,&lt;br /&gt;
    [(op_Mscratch V16ADDRri:$addr, v16i32:$dstsrc)],&lt;br /&gt;
    opcode&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  A set of multiclasses is used to handle Vector/Scalar &lt;br /&gt;
//  Masked/Unmasked combinations&lt;br /&gt;
//  MOVEI operations&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
multiclass FMOVEI_ALL&amp;lt;string operator, bits&amp;lt;3&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  // SI&lt;br /&gt;
  def SI : FMOVEI&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins SIMM16OP:$imm),&lt;br /&gt;
    operator # &amp;quot; $dst, $imm&amp;quot;,&lt;br /&gt;
    [],//[(set i32:$dst, simm16:$imm)],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // VI unmasked&lt;br /&gt;
  def VI_U : FMOVEI&amp;lt;&lt;br /&gt;
    (outs VR512W:$dst),&lt;br /&gt;
    (ins SIMM16OP:$imm),&lt;br /&gt;
    operator # &amp;quot; $dst, $imm&amp;quot;,&lt;br /&gt;
    [],//[(set v16i32:$dst, (splat simm16:$imm))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_V,&lt;br /&gt;
    0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
 let Constraints = &amp;quot;$dst = $oldvalue&amp;quot;, Uses = [MR_REG] in {&lt;br /&gt;
    // VI masked&lt;br /&gt;
    def VI_M : FMOVEI&amp;lt;&lt;br /&gt;
      (outs VR512W:$dst),&lt;br /&gt;
      (ins SIMM16OP:$imm, VR512W:$oldvalue),&lt;br /&gt;
      operator # &amp;quot;.m $dst, $imm&amp;quot;,&lt;br /&gt;
      [(set v16i32:$dst, (int_nuplus_vector_mixi32 (splat simm16:$imm), v16i32:$oldvalue))],&lt;br /&gt;
      opcode,&lt;br /&gt;
      Fmt_V,&lt;br /&gt;
      1&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Instruction class used to read/write special register through intrinics&lt;br /&gt;
// All these instructions are implemented using a move instruction&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
let DecoderNamespace = &amp;quot;Read_SPR&amp;quot; in {&lt;br /&gt;
  class READ_SPR&amp;lt;SpReg reg, string operator, Intrinsic read_intr&amp;gt; :&lt;br /&gt;
                FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
                  (outs GPR32:$dst),&lt;br /&gt;
                  (ins),&lt;br /&gt;
                  operator # &amp;quot; $dst&amp;quot;,&lt;br /&gt;
                  [(set i32:$dst, (read_intr))],&lt;br /&gt;
                  32,&lt;br /&gt;
                  Fmt_S,&lt;br /&gt;
                  Fmt_S&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    bits&amp;lt;6&amp;gt; dst;&lt;br /&gt;
&lt;br /&gt;
    let Inst{29-24} = 32; // opcode: move&lt;br /&gt;
    let Inst{23-18} = dst;&lt;br /&gt;
    let Inst{17-12} = reg.Register;&lt;br /&gt;
    let Inst{11-6} = 0;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
let DecoderNamespace = &amp;quot;Write_SPR&amp;quot; in {&lt;br /&gt;
  class WRITE_SPR&amp;lt;SpReg reg, string operator, Intrinsic read_intr&amp;gt; :&lt;br /&gt;
                FR_OneOp_Unmasked_32&amp;lt;&lt;br /&gt;
                  (outs),&lt;br /&gt;
                  (ins GPR32:$src),&lt;br /&gt;
                  operator # &amp;quot; $src&amp;quot;,&lt;br /&gt;
                  [(read_intr i32:$src)],&lt;br /&gt;
                  32,&lt;br /&gt;
                  Fmt_S,&lt;br /&gt;
                  Fmt_S&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    bits&amp;lt;6&amp;gt; src;&lt;br /&gt;
&lt;br /&gt;
    let Inst{29-24} = 32; // opcode: move&lt;br /&gt;
    let Inst{23-18} = reg.Register;&lt;br /&gt;
    let Inst{17-12} = src;&lt;br /&gt;
    let Inst{11-6} = 0;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Pseudo-instructions for alternate assembly syntax (never used by codegen).&lt;br /&gt;
//  These are aliases that require C++ handling to convert to the target&lt;br /&gt;
//  instruction, while InstAliases can be handled directly by tblgen.&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
class AsmPseudoInst&amp;lt;dag outs, dag ins, string asm&amp;gt;&lt;br /&gt;
  : InstNuPlus&amp;lt;outs, ins, asm, []&amp;gt; {&lt;br /&gt;
  let isPseudo = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class Pseudo&amp;lt;dag outs, dag ins, list&amp;lt;dag&amp;gt; pattern&amp;gt;&lt;br /&gt;
  : InstNuPlus&amp;lt;outs, ins, &amp;quot;Pseudo&amp;quot;, pattern&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  let isCodeGenOnly = 1;&lt;br /&gt;
  let isPseudo = 1;&lt;br /&gt;
  let Inst{31-0} = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
multiclass AtomicBinary&amp;lt;SDNode OpNode&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  def R : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$ptr, GPR32:$amt),&lt;br /&gt;
    [(set i32:$dst, (OpNode GPR32:$ptr, GPR32:$amt))]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  def I : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$ptr, SIMM9OP:$amt),&lt;br /&gt;
    [(set i32:$dst, (OpNode GPR32:$ptr, simm9:$amt))]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusInstrFormats.td&amp;diff=2114</id>
		<title>NuPlusInstrFormats.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusInstrFormats.td&amp;diff=2114"/>
				<updated>2019-06-21T14:42:50Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusInstrFormats.td to NaplesPUInstrFormats.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUInstrFormats.td]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUISelDAGToDAG.cpp&amp;diff=2111</id>
		<title>NaplesPUISelDAGToDAG.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUISelDAGToDAG.cpp&amp;diff=2111"/>
				<updated>2019-06-21T14:42:20Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusISelDAGToDAG.cpp to NaplesPUISelDAGToDAG.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The NuPlusDAGToDAGISel class is used to transform target independent LLVM DAG nodes into platform dependent nodes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusISelDAGToDAG.cpp - A dag to dag inst selector for NuPlus ------===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This pass transforms target independent LLVM DAG nodes into platform&lt;br /&gt;
// dependent nodes that map, for the most part, directly to target instructions.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
#define DEBUG_TYPE &amp;quot;nuplus-isel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusTargetMachine.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/CodeGen/SelectionDAGISel.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/IR/Intrinsics.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Compiler.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/Debug.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/ErrorHandling.h&amp;quot;&lt;br /&gt;
#include &amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;br /&gt;
using namespace llvm;&lt;br /&gt;
&lt;br /&gt;
namespace {&lt;br /&gt;
class NuPlusDAGToDAGISel : public SelectionDAGISel {&lt;br /&gt;
public:&lt;br /&gt;
  explicit NuPlusDAGToDAGISel(NuPlusTargetMachine &amp;amp;tm) : SelectionDAGISel(tm) {}&lt;br /&gt;
&lt;br /&gt;
  void Select(SDNode *N) override;&lt;br /&gt;
&lt;br /&gt;
  bool SelectInlineAsmMemoryOperand(const SDValue &amp;amp;Op, unsigned ConstraintCode,&lt;br /&gt;
                                    std::vector&amp;lt;SDValue&amp;gt; &amp;amp;OutOps) override;  &lt;br /&gt;
&lt;br /&gt;
  bool SelectADDRri(SDValue N, SDValue &amp;amp;Base, SDValue &amp;amp;Offset);&lt;br /&gt;
&lt;br /&gt;
  StringRef getPassName() const override {&lt;br /&gt;
    return &amp;quot;NuPlus DAG-&amp;gt;DAG Pattern Instruction Selection&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;NuPlusGenDAGISel.inc&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
} // end anonymous namespace&lt;br /&gt;
&lt;br /&gt;
bool NuPlusDAGToDAGISel::SelectADDRri(SDValue Addr, SDValue &amp;amp;Base,&lt;br /&gt;
                                     SDValue &amp;amp;Offset) {&lt;br /&gt;
&lt;br /&gt;
  if (FrameIndexSDNode *FIN = dyn_cast&amp;lt;FrameIndexSDNode&amp;gt;(Addr)) {&lt;br /&gt;
    Base = CurDAG-&amp;gt;getTargetFrameIndex(FIN-&amp;gt;getIndex(), MVT::i32);&lt;br /&gt;
    Offset = CurDAG-&amp;gt;getTargetConstant(0, SDLoc(Addr), MVT::i32);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||&lt;br /&gt;
      Addr.getOpcode() == ISD::TargetGlobalAddress)&lt;br /&gt;
    return false; // direct calls.&lt;br /&gt;
&lt;br /&gt;
  if (Addr.getOpcode() == ISD::ADD) {&lt;br /&gt;
        if (ConstantSDNode *CN = dyn_cast&amp;lt;ConstantSDNode&amp;gt;(Addr.getOperand(1))) {&lt;br /&gt;
      if (isInt&amp;lt;9&amp;gt;(CN-&amp;gt;getSExtValue())) {&lt;br /&gt;
        if (FrameIndexSDNode *FIN =&lt;br /&gt;
                dyn_cast&amp;lt;FrameIndexSDNode&amp;gt;(Addr.getOperand(0))) {&lt;br /&gt;
          Base = CurDAG-&amp;gt;getTargetFrameIndex(FIN-&amp;gt;getIndex(), MVT::i32);&lt;br /&gt;
        } else {&lt;br /&gt;
          Base = Addr.getOperand(0);&lt;br /&gt;
        }&lt;br /&gt;
        Offset = CurDAG-&amp;gt;getTargetConstant(CN-&amp;gt;getZExtValue(), SDLoc(Addr),&lt;br /&gt;
                                           MVT::i32);&lt;br /&gt;
        return true;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  Base = Addr;&lt;br /&gt;
  Offset = CurDAG-&amp;gt;getTargetConstant(0, SDLoc(Addr), MVT::i32);&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NuPlusDAGToDAGISel::Select(SDNode *N) {&lt;br /&gt;
 SDLoc DL(N);&lt;br /&gt;
 if (N-&amp;gt;isMachineOpcode())&lt;br /&gt;
   return; // Already selected.&lt;br /&gt;
&lt;br /&gt;
  SelectCode(N);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool NuPlusDAGToDAGISel::SelectInlineAsmMemoryOperand(&lt;br /&gt;
    const SDValue &amp;amp;Op, unsigned ConstraintCode, std::vector&amp;lt;SDValue&amp;gt; &amp;amp;OutOps) {&lt;br /&gt;
  SDValue Op0, Op1;&lt;br /&gt;
  switch (ConstraintCode) {&lt;br /&gt;
  default:&lt;br /&gt;
    return true;&lt;br /&gt;
&lt;br /&gt;
  case 'm': // memory&lt;br /&gt;
    SelectADDRri(Op, Op0, Op1);&lt;br /&gt;
    break;&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  OutOps.push_back(Op0);&lt;br /&gt;
  OutOps.push_back(Op1);&lt;br /&gt;
  return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
FunctionPass *llvm::createNuPlusISelDag(NuPlusTargetMachine &amp;amp;TM) {&lt;br /&gt;
  return new NuPlusDAGToDAGISel(TM);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusISelDAGToDAG.cpp&amp;diff=2112</id>
		<title>NuPlusISelDAGToDAG.cpp</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusISelDAGToDAG.cpp&amp;diff=2112"/>
				<updated>2019-06-21T14:42:20Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusISelDAGToDAG.cpp to NaplesPUISelDAGToDAG.cpp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUISelDAGToDAG.cpp]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPUCallingConv.td&amp;diff=2109</id>
		<title>NaplesPUCallingConv.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPUCallingConv.td&amp;diff=2109"/>
				<updated>2019-06-21T14:41:40Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusCallingConv.td to NaplesPUCallingConv.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
This file describes the conventions to use when a function is called, such as how to pass the arguments and how to return the function results.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
//===-- NuPlusCallingConv.td - Calling Conventions NuPlus ----*- tablegen -*-===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
// This describes the calling conventions for the NuPlus architectures.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def CC_NuPlus32 : CallingConv&amp;lt;[&lt;br /&gt;
&lt;br /&gt;
  // i1, i8 and i16 integers are promoted to i32 by the caller.&lt;br /&gt;
  CCIfType&amp;lt;[i1, i8, i16], CCPromoteToType&amp;lt;i32&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  CCIfType&amp;lt;[v16i8, v16i16], CCPromoteToType&amp;lt;v16i32&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[v8i8, v8i16, v8i32], CCPromoteToType&amp;lt;v8i64&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  // i32 f32 arguments get passed in integer registers if there is space.&lt;br /&gt;
  CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[i32, f32], CCAssignToReg&amp;lt;[S0, S1, S2, S3, S4, S5, S6, S7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
    // Vector arguments can be passed in their own registers, as above&lt;br /&gt;
  CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[v16i32, v16f32], CCAssignToReg&amp;lt;[V0, V1, V2, V3, V4, V5, V6, V7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  // Stick remaining registers onto stack, aligned by size&lt;br /&gt;
  CCIfType&amp;lt;[i32, f32], CCAssignToStack&amp;lt;4, 4&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[v16i32, v16f32], CCAssignToStack&amp;lt;64, 64&amp;gt;&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def RetCC_NuPlus32 : CallingConv&amp;lt;[&lt;br /&gt;
  CCIfType&amp;lt;[i1, i8, i16], CCPromoteToType&amp;lt;i32&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  CCIfType&amp;lt;[i32, f32], CCAssignToReg&amp;lt;[S0, S1, S2, S3, S4, S5]&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  CCIfType&amp;lt;[v16i8, v16i16], CCPromoteToType&amp;lt;v16i32&amp;gt;&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
  CCIfType&amp;lt;[v16i32, v16f32], CCAssignToReg&amp;lt;[V0, V1, V2, V3, V4, V5]&amp;gt;&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//Callee only needs to save the callee-save registers that are used in the body of its subroutine.&lt;br /&gt;
def NuPlusCSR : CalleeSavedRegs&amp;lt;(add (sequence &amp;quot;S%u&amp;quot;, 50, 57), MR_REG, FP_REG, RA_REG,&lt;br /&gt;
                               (sequence &amp;quot;V%u&amp;quot;, 56, 63))&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusCallingConv.td&amp;diff=2110</id>
		<title>NuPlusCallingConv.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusCallingConv.td&amp;diff=2110"/>
				<updated>2019-06-21T14:41:40Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusCallingConv.td to NaplesPUCallingConv.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPUCallingConv.td]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPURegisterInfo.td&amp;diff=2107</id>
		<title>NaplesPURegisterInfo.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPURegisterInfo.td&amp;diff=2107"/>
				<updated>2019-06-21T14:41:12Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusRegisterInfo.td to NaplesPURegisterInfo.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
The NuPlusRegisterInfo.td is used to define the nu+ hw registers and the nu+ register classes. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line='line'&amp;gt;&lt;br /&gt;
//===-- NuPlusRegisterInfo.td - NuPlus Register defs ---------*- tablegen -*-===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Declarations that describe the NuPlus register file&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
let Namespace = &amp;quot;NuPlus&amp;quot; in {&lt;br /&gt;
def sub_even : SubRegIndex&amp;lt;32&amp;gt;;&lt;br /&gt;
def sub_odd  : SubRegIndex&amp;lt;32, 32&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class NuPlusReg&amp;lt;bits&amp;lt;16&amp;gt; Enc, string n&amp;gt; : Register&amp;lt;n&amp;gt; {&lt;br /&gt;
  let HWEncoding = Enc;&lt;br /&gt;
  let Namespace = &amp;quot;NuPlus&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class NuPlusRegWithSubRegs&amp;lt;bits&amp;lt;16&amp;gt; Enc, string n, list&amp;lt;Register&amp;gt; subregs&amp;gt;&lt;br /&gt;
  : RegisterWithSubRegs&amp;lt;n, subregs&amp;gt; {&lt;br /&gt;
  let HWEncoding = Enc;&lt;br /&gt;
  let Namespace = &amp;quot;NuPlus&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// NuPlus 32-bit registers&lt;br /&gt;
class NuPlusGPRReg&amp;lt;bits&amp;lt;16&amp;gt; Enc, string n&amp;gt; : NuPlusReg&amp;lt;Enc, n&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//  Registers&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // General Purpose scalar registers&lt;br /&gt;
  foreach i = 0-57 in {&lt;br /&gt;
    def S#i : NuPlusGPRReg&amp;lt;i, &amp;quot;s&amp;quot;#i&amp;gt;, DwarfRegNum&amp;lt;[i]&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //trap register&lt;br /&gt;
  def TR_REG : NuPlusGPRReg&amp;lt;58, &amp;quot;tr&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[58]&amp;gt;;&lt;br /&gt;
  //mask register&lt;br /&gt;
  def MR_REG : NuPlusGPRReg&amp;lt;59, &amp;quot;rm&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[59]&amp;gt;;&lt;br /&gt;
  //frame pointer&lt;br /&gt;
  def FP_REG : NuPlusGPRReg&amp;lt;60, &amp;quot;fp&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[60]&amp;gt;;&lt;br /&gt;
  //stack pointer&lt;br /&gt;
  def SP_REG : NuPlusGPRReg&amp;lt;61, &amp;quot;sp&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[61]&amp;gt;;&lt;br /&gt;
  //return address&lt;br /&gt;
  def RA_REG : NuPlusGPRReg&amp;lt;62, &amp;quot;ra&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[62]&amp;gt;;&lt;br /&gt;
  //PC&lt;br /&gt;
  def PC_REG : NuPlusGPRReg&amp;lt;63, &amp;quot;pc&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[63]&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
  // General Purpose vectorial registers&lt;br /&gt;
  foreach i = 0-63 in {&lt;br /&gt;
    def V#i : NuPlusGPRReg&amp;lt;i, &amp;quot;v&amp;quot;#i&amp;gt;, DwarfRegNum&amp;lt;[!add(i, 64)]&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Register Classes&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
// This register class should not be used to hold i64/f64 values, use the GPR64&lt;br /&gt;
// register class for that. The i64/f64 type is included here to allow i64/f64&lt;br /&gt;
// patterns using the instructions.&lt;br /&gt;
def GPR32 : RegisterClass&amp;lt;&amp;quot;NuPlus&amp;quot;, [i32, f32], 32, (add (sequence &amp;quot;S%u&amp;quot;, 0, 57),&lt;br /&gt;
  TR_REG, MR_REG, FP_REG, SP_REG, RA_REG, PC_REG)&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def VR512W : RegisterClass&amp;lt;&amp;quot;NuPlus&amp;quot;, [v16i32, v16f32, v16i8, v16i16], 512, (sequence &amp;quot;V%u&amp;quot;, 0, 63)&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlusRegisterInfo.td&amp;diff=2108</id>
		<title>NuPlusRegisterInfo.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlusRegisterInfo.td&amp;diff=2108"/>
				<updated>2019-06-21T14:41:12Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlusRegisterInfo.td to NaplesPURegisterInfo.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPURegisterInfo.td]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NuPlus.td&amp;diff=2106</id>
		<title>NuPlus.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NuPlus.td&amp;diff=2106"/>
				<updated>2019-06-21T14:39:58Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlus.td to NaplesPU.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPU.td]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU.td&amp;diff=2105</id>
		<title>NaplesPU.td</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU.td&amp;diff=2105"/>
				<updated>2019-06-21T14:39:57Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page NuPlus.td to NaplesPU.td&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tablegen Files]]&lt;br /&gt;
The NuPlus.td file contains the definition of the Target class '''NuPlus''' (defined in &amp;quot;compiler/include/llvm/Target/Target.td&amp;quot;). The file also contains the definition of the '''NuPlusInstrInfo''', '''NuPlusAsmParser''' and '''NuPlusAsmWriter''' required by the '''Target''' class. In addition, we avoid using instruction itineraries for scheduling. Itineraries are details reservation tables for each instruction class. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line='line'&amp;gt;&lt;br /&gt;
//===-- NuPlus.td - Describe the NuPlus Target Machine -------*- tablegen -*-===//&lt;br /&gt;
//&lt;br /&gt;
//                     The LLVM Compiler Infrastructure&lt;br /&gt;
//&lt;br /&gt;
// This file is distributed under the University of Illinois Open Source&lt;br /&gt;
// License. See LICENSE.TXT for details.&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Target-independent interfaces which we are implementing&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
include &amp;quot;llvm/Target/Target.td&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Register File, Calling Conv, Instruction Descriptions&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
include &amp;quot;NuPlusRegisterInfo.td&amp;quot;&lt;br /&gt;
include &amp;quot;NuPlusCallingConv.td&amp;quot;&lt;br /&gt;
include &amp;quot;NuPlusInstrInfo.td&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def NuPlusInstrInfo : InstrInfo;&lt;br /&gt;
&lt;br /&gt;
def NuPlusAsmParser : AsmParser {&lt;br /&gt;
  bit ShouldEmitMatchRegisterName = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
// Declare the target which we are implementing&lt;br /&gt;
//===----------------------------------------------------------------------===//&lt;br /&gt;
&lt;br /&gt;
def NuPlusAsmWriter : AsmWriter {&lt;br /&gt;
  string AsmWriterClassName  = &amp;quot;InstPrinter&amp;quot;;&lt;br /&gt;
  bit isMCAsmWriter = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def : Processor&amp;lt;&amp;quot;nuplus&amp;quot;, NoItineraries, []&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
def NuPlus : Target {&lt;br /&gt;
  // Pull in Instruction Info:&lt;br /&gt;
  let InstructionSet = NuPlusInstrInfo;&lt;br /&gt;
  let AssemblyParsers  = [NuPlusAsmParser];&lt;br /&gt;
  let AssemblyWriters = [NuPlusAsmWriter];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_LLVM_Documentation&amp;diff=2102</id>
		<title>NaplesPU LLVM Documentation</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_LLVM_Documentation&amp;diff=2102"/>
				<updated>2019-06-21T14:37:29Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page Nu+ LLVM Documentation to NaplesPU LLVM Documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The main task of the backend is to generate NPU assembly code from the LLVM IR obtained by the Clang frontend. It also handles object representation of classes needed to create the assembler and the disassembler.&lt;br /&gt;
The NPU backend is contained in the '''NaplesPU''' folder under &amp;quot;compiler/lib/Target&amp;quot; directory. It contains several files, each implementing a specific class of the LLVM Framework.&lt;br /&gt;
&lt;br /&gt;
An LLVM backend is constructed on two types of file, C++ and TableGen source files. Refer to section [[#TableGen | TableGen]] to get a detailed explanation of the latters.&lt;br /&gt;
&lt;br /&gt;
== Required reading ==&lt;br /&gt;
Before working on LLVM, you should be familiar with some things. In particular: &lt;br /&gt;
# [https://en.wikipedia.org/wiki/Basic_block '''Basic Blocks''']&lt;br /&gt;
# [https://en.wikipedia.org/wiki/Static_single_assignment_form '''SSA''' (Static Single Assignment) form]&lt;br /&gt;
# [https://en.wikipedia.org/wiki/Abstract_syntax_tree '''AST''' (Abstract Syntax tree)] &lt;br /&gt;
# [https://en.wikipedia.org/wiki/Directed_acyclic_graph '''DAG''' Direct Acyclic Graph].&lt;br /&gt;
&lt;br /&gt;
In addition to general aspects about compilers, it is recommended to review the following topics:&lt;br /&gt;
#[http://www.aosabook.org/en/llvm.html '''LLVM architecture''']&lt;br /&gt;
#[http://llvm.org/docs/LangRef.html '''LLVM Intermediate Representation'''] &lt;br /&gt;
&lt;br /&gt;
See the following textbook for other information [http://books.tarsoit.com/Getting%20Started%20with%20LLVM%20Core%20Libraries.pdf Getting Started with LLVM Core Libraries] and [https://github.com/iBreaker/book/blob/master/LLVM%20Cookbook.pdf LLVM Cookbook].&lt;br /&gt;
&lt;br /&gt;
See also [https://eli.thegreenplace.net/2012/11/24/life-of-an-instruction-in-llvm this article] to get an overview of the main CodeGenerator phases.&lt;br /&gt;
&lt;br /&gt;
== TableGen ==&lt;br /&gt;
&lt;br /&gt;
TableGen is a record-oriented language used to describe the target-specific information. It is written by the LLVM team in order to simplify the back-end development and to avoid potential code redundancy. For example, by using TableGen, if some feature of the target-specific register file changes, you do not need to modify different files wherever the register appears but you need only to modify the ''.td'' file that contains its definition. Actually, the TableGen is used to define instruction formats, instructions, registers, pattern-matching DAGs, instruction selection matching order, calling conventions, and target platform properties.&lt;br /&gt;
&lt;br /&gt;
For other information, check the [http://llvm.org/docs/TableGen/index.html TableGen Documentation]&lt;br /&gt;
&lt;br /&gt;
== Backend Description ==&lt;br /&gt;
&lt;br /&gt;
This section shows how is implemented the backend support for NPU within LLVM.&lt;br /&gt;
&lt;br /&gt;
=== Target Definition ===&lt;br /&gt;
&lt;br /&gt;
The target-specific information is explained in TableGen files. The custom target is defined by creating a new [[NaplesPU.td]] file,  in which the target itself is described. This file contains the implementation of the target-independent interfaces provided by ''Target.td''. Implementations are done by using the class inheritance mechanism.&lt;br /&gt;
&lt;br /&gt;
The code below is the ''Target'' class definition that should be implemented in [[NaplesPU.td]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class Target {&lt;br /&gt;
  InstrInfo InstructionSet;&lt;br /&gt;
  list&amp;lt;AsmParser&amp;gt; AssemblyParsers = [DefaultAsmParser];&lt;br /&gt;
  list&amp;lt;AsmParserVariant&amp;gt; AssemblyParserVariants = [DefaultAsmParserVariant];&lt;br /&gt;
  list&amp;lt;AsmWriter&amp;gt; AssemblyWriters = [DefaultAsmWriter];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This file should also include the other defined ''.td'' target-related files. The target definition is done as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;def : Processor&amp;lt;&amp;quot;naplespu&amp;quot;, NoItineraries, []&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ''Processor'' is a class defined in ''Target.td'':&lt;br /&gt;
&amp;lt;code&amp;gt;class Processor&amp;lt;string n, ProcessorItineraries pi, list&amp;lt;SubtargetFeature&amp;gt; f&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
* ''n'' is the chipset name, used in the command line option ''-mcpu'' to determine the appropriate chip.&lt;br /&gt;
* ''p'' is the processor itinerary, as described in the theoretical description of the LLVM ''instruction scheduling'' phase. ''NoItinerary'' means that no itinerary is defined.&lt;br /&gt;
* ''f'' is a list of target features.&lt;br /&gt;
&lt;br /&gt;
=== Registers Definition ===&lt;br /&gt;
The target-specific registers are defined in [[NaplesPURegisterInfo.td]]. LLVM provides two ways to define a register, both of them declared in ''Target.td''. The first one is used to define a simple scalar register and follows the declaration below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Register&amp;lt;string n, list&amp;lt;string&amp;gt; altNames = []&amp;gt;&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
where ''n'' is the register name, while ''altNames'' is a list of register alternative names. &lt;br /&gt;
&lt;br /&gt;
The second method to define a register is to inherit from the class declared below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class RegisterWithSubRegs&amp;lt;string n, list&amp;lt;Register&amp;gt; subregs&amp;gt; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This second way is used when it is required to define a register that is a collection of ''n'' sub-registers.&lt;br /&gt;
There is also a third way to define registers. It consists of defining a ''super-register'', that is a pseudo-register resulting of the combination of other sub-registers. It is useful when there is no architectural support for larger registers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class RegisterTuples&amp;lt;list&amp;lt;SubRegIndex&amp;gt; Indices, list&amp;lt;dag&amp;gt; Regs&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, the following code is the declaration of the register class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class NaplesPUGPRReg&amp;lt;string n&amp;gt; : Register &amp;lt;n&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, registers can be instantiated as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
foreach i = 0-57 in {&lt;br /&gt;
    def S#i : NaplesPUGPRReg&amp;lt;&amp;quot;s&amp;quot;#i&amp;gt;, DwarfRegNum&amp;lt;[i]&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
def SP_REG : NaplesPUGPRReg&amp;lt;&amp;quot;sp&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[61]&amp;gt;; //stack pointer&lt;br /&gt;
...&lt;br /&gt;
foreach i = 0-63 in {&lt;br /&gt;
    def V#i : NaplesPUGPRReg&amp;lt;&amp;quot;v&amp;quot;#i&amp;gt;, DwarfRegNum&amp;lt;[!add(i, 64)]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The instantiation reflects the custom target hardware architecture, with a set of scalar registers and a set of vectorial ones.&lt;br /&gt;
Each register inherits also from the''DwarfRegNum'' assigning to it an incremental number. This is useful for the internal identification of registers, consistent with the ''DWARF'' standard.&lt;br /&gt;
&lt;br /&gt;
Now that registers are defined they must belong to classes in order to define the allocation of them.&lt;br /&gt;
&lt;br /&gt;
LLVM provides the ''RegisterClass'' defined as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class RegisterClass&amp;lt;string namespace, list&amp;lt;ValueType&amp;gt; regTypes, int alignment, dag regList&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which:&lt;br /&gt;
&lt;br /&gt;
* ''namespace'' is the namespace associate to it;&lt;br /&gt;
* ''regTypes'' is a list of ''ValueType'' values indicating the types of variables that can be allocated into them;&lt;br /&gt;
* ''alignment'' is the alignment associated to the registers in the ''RegisterClass'';&lt;br /&gt;
* ''regList'' is the list of registers that belong to the class. Since the parameter type is ''dag'', TableGen provides operands to define a set of registers in terms of a set of operators.&lt;br /&gt;
&lt;br /&gt;
For example, to match our target features it is necessary to define two classes:&lt;br /&gt;
* GPR32, that is the abstraction of 32-bit wide scalar registers;&lt;br /&gt;
* VR512W, that are the abstraction of 512-bit wide vectorial registers; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def GPR32 : RegisterClass&amp;lt;&amp;quot;NaplesPU&amp;quot;, [i32, f32, i64, f64], 32, (add (sequence &amp;quot;S%u&amp;quot;, 0, 57),&lt;br /&gt;
  TR_REG, MR_REG, FP_REG, SP_REG, RA_REG, PC_REG)&amp;gt;;&lt;br /&gt;
def VR512W : RegisterClass&amp;lt;&amp;quot;NaplesPU&amp;quot;, [v16i32, v16f32, v16i8, v16i16], 512, (sequence &amp;quot;V%u&amp;quot;, 0, 63)&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling Convention ===&lt;br /&gt;
&lt;br /&gt;
This section shows how to define the ''calling convention'', that is how ''parameters'' are passed to sub-functions, and how the ''return value'' is sent back to the caller. &lt;br /&gt;
&lt;br /&gt;
The calling convention is defined in the [[NaplesPUCallingConv.td]] by using the classes defined in the ''TargetCallingConv.td'' file. &lt;br /&gt;
&lt;br /&gt;
In our purposes, it's required to define the calling convention in terms of the registers used to pass the arguments to the callee. &lt;br /&gt;
LLVM provides the ''CallingConv'' class defined below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class CallingConv&amp;lt;list&amp;lt;CCAction&amp;gt; actions&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This class requires a list of ''CCAction''. ''TargetCallingConv.td'' contains a set of ''CCAction'' derived classes that must be used to define the sub-function calling behaviour.&lt;br /&gt;
&lt;br /&gt;
The calling convention for the custom target device is defined by using the first ''eight'' registers, and then the stack for the remaining parameters. It means that for 32-bit variables, they are passed to the callee by using the registers Si, where i = 0..7.&lt;br /&gt;
The same schema is adopted for vectorial variables. &lt;br /&gt;
&lt;br /&gt;
The calling convention should also take care of the passing of type that is not natively supported by the target. In this case, the solution adopted is the type promotion. The mechanism is simple: it consists of promoting the unsupported type to a supported one. It can be easily implemented by only using the ''CCAction'' classes provided by LLVM.&lt;br /&gt;
By using the just described approach, ''i1, i8, i16'' are promoted to ''i32'' while ''v16i8, v16i16'' are promoted to ''v16i32''. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def CC_NaplesPU : CallingConv&amp;lt;[&lt;br /&gt;
  CCIfType&amp;lt;[i1, i8, i16], CCPromoteToType&amp;lt;i32&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[v16i8, v16i16], CCPromoteToType&amp;lt;v16i32&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[i32, f32], CCAssignToReg&amp;lt;[S0, S1, S2, S3, S4, S5, S6, S7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[v16i32, v16f32], CCAssignToReg&amp;lt;[V0, V1, V2, V3, V4, V5, V6, V7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[i32, f32], CCAssignToStack&amp;lt;4, 4&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[v16i32, v16f32], CCAssignToStack&amp;lt;64, 64&amp;gt;&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The calling convention for NPU in terms of results returning mechanism is realized by passing them in the first six registers. &lt;br /&gt;
&lt;br /&gt;
It could be also possible that the return type does not correspond to any native target type. The solution is ''promoting''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def RetCC_NaplesPU32 : CallingConv&amp;lt;[&lt;br /&gt;
CCIfType&amp;lt;[i1, i8, i16], CCPromoteToType&amp;lt;i32&amp;gt;&amp;gt;,&lt;br /&gt;
CCIfType&amp;lt;[i32, f32], CCAssignToReg&amp;lt;[S0, S1, S2, S3, S4, S5]&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LLVM also provides a mechanism to define the registers that the callee must save before starting the function execution. The mechanism consists in defining an instance of the class ''CalleeSavedRegs'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class CalleeSavedRegs&amp;lt;dag saves&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ''saves'' is the list of registers to be saved. &lt;br /&gt;
&lt;br /&gt;
For example, in NPU, the callee saved registers are defined as follows:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code&amp;gt;def NaplesPUCSR : CalleeSavedRegs&amp;lt;(add (sequence &amp;quot;S%u&amp;quot;, 50, 57), MR_REG, FP_REG, RA_REG, (sequence &amp;quot;V%u&amp;quot;, 56, 63))&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ISA Support ===&lt;br /&gt;
&lt;br /&gt;
In order to define the LLVM support for NPU, the next step is to handle the target-specific code generation by implementing its ''ISA'' (Instruction Set Architecture) in LLVM. &lt;br /&gt;
In order to describe it, TableGen provides the class ''Instruction'' located in ''Target.td''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class Instruction {&lt;br /&gt;
  string Namespace = &amp;quot;&amp;quot;;&lt;br /&gt;
  dag OutOperandList;       &lt;br /&gt;
  dag InOperandList;     &lt;br /&gt;
  string AsmString = &amp;quot;&amp;quot;; &lt;br /&gt;
  list&amp;lt;dag&amp;gt; Pattern;&lt;br /&gt;
  list&amp;lt;Register&amp;gt; Uses = []; &lt;br /&gt;
  list&amp;lt;Register&amp;gt; Defs = [];&lt;br /&gt;
  list&amp;lt;Predicate&amp;gt; Predicates = [];&lt;br /&gt;
  int Size = 0;&lt;br /&gt;
  bit isReturn     = 0;     &lt;br /&gt;
  bit isBranch     = 0;    &lt;br /&gt;
  bit isPseudo     = 0;    &lt;br /&gt;
  bit isCodeGenOnly = 0;&lt;br /&gt;
  bit isAsmParserOnly = 0;&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As it is clear, the ''Instruction'' class provides a lot of member variable to describe an instruction. The following are a subset that is used for our purposes:&lt;br /&gt;
&lt;br /&gt;
* ''OutOperandList'' is the set of output operands of the instruction, defined as of ''dag'' type.&lt;br /&gt;
* ''InOperandList'' is the set of input operands of the instruction, defined as of ''dag'' type.&lt;br /&gt;
* ''AsmString'' is the''.s'' format to print the instruction with.&lt;br /&gt;
* ''isReturn'' defines the instruction as a ''return'' one.&lt;br /&gt;
* ''isBranch'' defines the instruction as a ''branch'' one, that is, it breaks the sequential control flow.&lt;br /&gt;
* ''isPseudo'' defines the instruction as a ''pseudo'' one, or rather an instruction for which there is not a corresponding machine instruction.&lt;br /&gt;
* ''isCodeGenOnly'', ''isAsmParserOnly'' and ''usesCustomInserter'' are also defining a pseudo-instruction, but with different behaviour. The first field is describing a pseudo-instruction that is used for CodeGen modeling purposes while the second one is describing a pseudo-instruction used by the assembler parser. The third one tells that the pseudo-instruction needs to be manually lowered to a machine instruction.&lt;br /&gt;
* ''Uses'' and ''Defs'' are lists of registers that are respectively read and written by the instruction. &lt;br /&gt;
* ''Predicates'' are logical expressions that must be checked in the Instruction Selection phase.&lt;br /&gt;
* ''Pattern'' is a list of ''dag'', each of them explains a DAG Pattern for the instruction used by the instruction selector to turn a set of ''SelectionDAG}'' nodes in the corresponding target-specific instruction. &lt;br /&gt;
&lt;br /&gt;
In order to handle the target platform ISA complexity it has been adapted a hierarchical schema of classes, each one represents a specific instruction format. &lt;br /&gt;
&lt;br /&gt;
First of all it is defined a generic format for the target-specific instruction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class InstNaplesPU&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern&amp;gt;&lt;br /&gt;
          : Instruction {&lt;br /&gt;
  field bits&amp;lt;32&amp;gt; Inst;&lt;br /&gt;
  let Namespace = &amp;quot;MyTarget&amp;quot;;&lt;br /&gt;
  let Size = 4;&lt;br /&gt;
  dag OutOperandList = outs;&lt;br /&gt;
  dag InOperandList = ins;&lt;br /&gt;
  let AsmString   = asmstr;&lt;br /&gt;
  let Pattern = pattern;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All instruction classes are inherited by the one above, specifying what the instruction bits are representing. Since the target supports different types of instruction format, for each of them is defined as a different class. Each class is then defined in terms of other sub-classes. For example, it may be useful to analyze the ''R'' format, that is the instruction format used to handle logical and arithmetic operations and memory operations. &lt;br /&gt;
By analyzing the instruction type it may be useful to distinguish among different sub-types, by structuring a hierarchy.&lt;br /&gt;
&lt;br /&gt;
[[File:Formats_hierarchy.jpg|This picture shows how the classes are inherited from the FR class.]]&lt;br /&gt;
&lt;br /&gt;
In this way, we shall define a set of classes implementing the hierarchy exposed, from the root, that represents the most generic R-type instruction, to leaves. Since the instruction format requires a set of ''FMT'' bits, it is also necessary to define a class to handle them:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class Fmt&amp;lt;bit val&amp;gt; {&lt;br /&gt;
  bit Value = val;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The root class is defined as the most general class of the hierarchy. For this reason, the second source operand is not defined. The derived class, implementing the two-operand R-type instruction, will properly set the related field. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class FR&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : InstNaplesPU&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dst;&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src0;&lt;br /&gt;
  let Inst{31-30} = 0;&lt;br /&gt;
  let Inst{29-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-12} = src0;&lt;br /&gt;
  let Inst{5} = 0; //unused&lt;br /&gt;
  let Inst{4} = 0; //No 64-bit support&lt;br /&gt;
  let Inst{3} = fmt2.Value;&lt;br /&gt;
  let Inst{2} = fmt1.Value;&lt;br /&gt;
  let Inst{1} = fmt0.Value;&lt;br /&gt;
  let Inst{0} = 1;&lt;br /&gt;
  let Uses=[MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR&amp;lt;outs, ins, asmstr, pattern, opcode, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src1;&lt;br /&gt;
  let Inst{11-6} = src1;&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp&amp;lt;outs, ins, asmstr, pattern, opcode, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
   let Inst{11-6} = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code above is showing the implementation of the classes hierarchy illustrated above. &lt;br /&gt;
All the other instruction format are implementing by using the same method.&lt;br /&gt;
&lt;br /&gt;
However, the class definition method is not a flexible way to explain the commonalities among more than two definition instances. As a solution, LLVM provides the ''multiclass'' construct. For example, if an arithmetic instruction is designed to work both with an immediate value or two registers, the class construct forces to have implementation as described below. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class rrinst&amp;lt;int opc, string asmstr&amp;gt;&lt;br /&gt;
  : inst&amp;lt;opc, !strconcat(asmstr, &amp;quot; $dst, $src1, $src2&amp;quot;),&lt;br /&gt;
         (ops GPR:$dst, GPR:$src1, GPR:$src2)&amp;gt;;&lt;br /&gt;
class riinst&amp;lt;int opc, string asmstr&amp;gt;&lt;br /&gt;
  : inst&amp;lt;opc, !strconcat(asmstr, &amp;quot; $dst, $src1, $src2&amp;quot;),&lt;br /&gt;
         (ops GPR:$dst, GPR:$src1, Imm:$src2)&amp;gt;;&lt;br /&gt;
def ADD_rr : rrinst&amp;lt;0b111, &amp;quot;add&amp;quot;&amp;gt;;&lt;br /&gt;
def ADD_ri : riinst&amp;lt;0b111, &amp;quot;add&amp;quot;&amp;gt;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The usage of the class construct in this context is quietly unfeasible. Differently, below is showed how clean is the approach using the ''multiclass'' construct.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
multiclass ri_inst&amp;lt;int opc, string asmstr&amp;gt; {&lt;br /&gt;
  def _rr : inst&amp;lt;opc, !strconcat(asmstr, &amp;quot; $dst, $src1, $src2&amp;quot;),&lt;br /&gt;
                 (ops GPR:$dst, GPR:$src1, GPR:$src2)&amp;gt;;&lt;br /&gt;
  def _ri : inst&amp;lt;opc, !strconcat(asmstr, &amp;quot; $dst, $src1, $src2&amp;quot;),&lt;br /&gt;
                 (ops GPR:$dst, GPR:$src1, Imm:$src2)&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
defm ADD : ri_inst&amp;lt;0b111, &amp;quot;add&amp;quot;&amp;gt;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ''multiclass'' construct is used to handle different register types for arithmetic operations. Therefore, despite defining several classes, one for each combination of scalar and vectorial registers as source operands, the usage of the ''multiclass'' construct is the best solution to do it. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
multiclass FArithInt_TwoOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  def SSS_32 : FR_TwoOp&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src0, i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pattern Recognition ===&lt;br /&gt;
&lt;br /&gt;
The ''Instruction Selection'' phase tries to substitute the IR instruction with the target-specific one. This pass is structured in two ways implemented in ''Select()'' method of the ''SelectionDAGISel''  class: the first way tries to find an instruction matching by looking at the target description provided by the compiled TableGen files, while the second way is looking to a custom code matching defined by the user. &lt;br /&gt;
&lt;br /&gt;
Consequently, it is useful to define instruction patterns in order to help the ''Select'' method to find a proper match. TableGen defines a set of classes that are used to declare a pattern. &lt;br /&gt;
&lt;br /&gt;
For example, an important concept implemented is the ''Pattern Fragment'', that is a reusable chunk of DAG that matches specific nodes. LLVM provides few implementation of the mentioned class, starting from the ''PatFrag'', that is the most general class, to ''OutPatFrag'', ''PatLeaf'' and ''ImmLeaf'' inherited from the first one. &lt;br /&gt;
&lt;br /&gt;
The''PatFrag'' definition is showed below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class PatFrag&amp;lt;dag ops, dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm&amp;gt; : SDPatternOperator&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
* ''ops'' represents the input operands;&lt;br /&gt;
* ''frag'' is the fragment to be matched;&lt;br /&gt;
* ''pred'' is the predicate to be satisfied in order to apply the transformation;&lt;br /&gt;
* ''xform'' is the transformation to be applied if all the previous points are fulfilled.&lt;br /&gt;
&lt;br /&gt;
In NaplesPU, the ''PatFrag'' class is used to handle the ''store'' operations, in terms of the address space they refer to. In our purposes, it is required to define a store operation in the global memory if and only if it is satisfied with a condition on the address space identification number. Otherwise, the memory operation refers to the ''scratchpad'' address space.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def MemStore : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                       (store node:$val, node:$ptr), [{&lt;br /&gt;
               if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
                  return !cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;isTruncatingStore();&lt;br /&gt;
               else&lt;br /&gt;
                  return false;}]&amp;gt;;&lt;br /&gt;
def ScratchpadStore : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                              (store node:$val, node:$ptr), [{&lt;br /&gt;
               if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
                 return !cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;isTruncatingStore();&lt;br /&gt;
               else&lt;br /&gt;
                 return false;}]&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''PatLeaf'' is the a ''PatFrag'' sub-class, deprived of the transformation and the pattern parameters, used, for example, to handle the ''immediate'' values transformation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def simm16 : PatLeaf&amp;lt;(imm), [{ return isInt&amp;lt;16&amp;gt;(N-&amp;gt;getSExtValue()); }]&amp;gt;;&lt;br /&gt;
def simm9 : PatLeaf&amp;lt;(imm), [{ return isInt&amp;lt;9&amp;gt;(N-&amp;gt;getSExtValue()); }]&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern exposed is used to recognise if the immediate is 9-bit wide or 16-bit wide. &lt;br /&gt;
LLVM also provides a class that is used to define more complex patterns than the ones explained above. It is typically used to handle the ''addressing modes''. &lt;br /&gt;
The described behaviour is implemented in the class ''ComplexPattern'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class ComplexPattern&amp;lt;ValueType ty, int numops, string fn, list&amp;lt;SDNode&amp;gt; roots = [], list&amp;lt;SDNodeProperty&amp;gt; props = []&amp;gt; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
* ''ty'' is the type associated to the pattern;&lt;br /&gt;
* ''numops'' is the number of operands returned by the function;&lt;br /&gt;
* ''n'' is the name of the function;&lt;br /&gt;
* ''roots'' is the list of possible \textit{root nodes} of the sub-DAG to match;&lt;br /&gt;
* ''props'' is a list of possible predicates to match. &lt;br /&gt;
&lt;br /&gt;
As mentioned above, this pattern is usually used to handle the addressing modes. In our purpose, the pattern is used to evaluate the address as ''base plus offset''. For this reason, it is necessary to define a proper function in the ''Select()'' method [[NaplesPUISelDAGToDAG.cpp]] file.&lt;br /&gt;
&lt;br /&gt;
The following line shows how to define a ''ComplexPattern'' instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;def ADDRri:ComplexPattern&amp;lt;iPTR, 2, &amp;quot;SelectADDRri&amp;quot;, [frameindex], []&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern above calls the method ''SelectADDRri'' defined in the [[NaplesPUISelDAGToDAG.cpp]] when an SDNode is of ''iPTR'' type.&lt;br /&gt;
&lt;br /&gt;
=== Instructions definition ===&lt;br /&gt;
This section describes how to use the formats defined in [[NaplesPUInstrFormats.td]] to instantiate the target-specific instructions. &lt;br /&gt;
Because of the instruction formats definition described before, the target-specific ISA can be realized by simply instantiating the formats themselves. &lt;br /&gt;
&lt;br /&gt;
For instance, the ''ADD'' instruction is of the ''arithmetic'' format, that is implemented by using the ''multiclass'' construct. As a consequence, the instantiation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; defm ADD:FArithInt_TwoOp&amp;lt;&amp;quot;add&amp;quot;, add, 4&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other arithmetic instructions are implemented in a similar way as above.&lt;br /&gt;
Thanks to the ''multiclass'' construct a single definition instantiates scalar and vector variants of the ''ADD'' instruction.&lt;br /&gt;
&lt;br /&gt;
Instruction definition is located in [[NaplesPUInstrInfo.td]].&lt;br /&gt;
 &lt;br /&gt;
There are some cases in which the TableGen generated outputs are not enough to produce a legalized DAG composed of only machine instruction nodes. In these cases could be useful to define a pattern that helps the instruction selection algorithm to find a match. Beyond the ''PatFrag'' class, LLVM provides an explicit way to force a pattern matching through the class ''Pat'', defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; class Pat&amp;lt;dag pattern, dag result&amp;gt; : Pattern&amp;lt;pattern, [result]&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance, consider the frontend intrinsic ''int_npu_vector_mix32''. It is converted in a target-specific node through the ''Pat'' class, as explained below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; def : Pat&amp;lt;(int_npu_vector_mixf32 v16f32:$src0, v16f32:$oldvalue),  (MOVE_VV_M_32 v16f32:$src0, v16f32:$oldvalue)&amp;gt;; } &amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
As a result of the pattern application, the considered node is transformed into ''MOVE_VV_M_32'' that is a target-specific node.&lt;br /&gt;
 &lt;br /&gt;
Even though the use of ''Pat'' s an easy-to-apply solution to help the instruction selector, its power is limited to simple substitutions. &lt;br /&gt;
More complex behaviors have to be managed manually in the ''Lowering'' Pass.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Selection Lowering ===&lt;br /&gt;
&lt;br /&gt;
Because the TableGen description is not enough to have a full substitution of target-dependent nodes, LLVM provides a ''C++'' file to implement the lowering pass, that [[NaplesPUISelLowering.cpp]].&lt;br /&gt;
In our purpose, the lowering mainly concerns the ''pseudo-instructions'' defined in [[NaplesPUInstrInfo.td]]. Recall that a pseudo-instruction is a special instruction that does not map to any machine code. For example, it is helpful to analyze how is managed the ''load'' operation associated to a 32-bit immediate value.&lt;br /&gt;
The 32-bit instruction format allows the ''move'' operation for an immediate operand that is at most 16-bit wide. To handle wider immediate operands it is necessary to find a solution. &lt;br /&gt;
By looking at [[NaplesPUInstrInfo.td]], the mentioned operation, named ''LoadI32'', is defined as a pseudo-instruction with ''usesCustomInserter'' bit set, as showed below. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def LoadI32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$val),&lt;br /&gt;
    [(set i32:$dst, (i32 imm:$val))]&amp;gt;;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LLVM APIs are designed to deal with DAG nodes. To handle the ''Load32I'' operation, ''MOVEIH'' and ''MOVEIL'' instructions are used. For this reason, the 32-bit value is split into two sub-values, each one of 16-bit wide that can be used to build the machine instruction nodes. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
MachineBasicBlock *&lt;br /&gt;
NaplesPUTargetLowering::EmitInstrWithCustomInserter(MachineInstr &amp;amp;MI,&lt;br /&gt;
                                                 MachineBasicBlock *BB) const {&lt;br /&gt;
  switch (MI.getOpcode()) {&lt;br /&gt;
  case NaplesPU::LoadI32:&lt;br /&gt;
  	return EmitLoadI32(&amp;amp;MI, BB);&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ''LoadI32'' is split into two machine instruction, one that uses the MOVEIH instruction and the other that uses the MOVEIL instruction, as the code below explains.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
MachineBasicBlock* EmitLoadI32(...) const {&lt;br /&gt;
  DebugLoc DL = MI-&amp;gt;getDebugLoc();&lt;br /&gt;
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();&lt;br /&gt;
  int64_t ImmOp = MI-&amp;gt;getOperand(1).getImm(); &lt;br /&gt;
if((ImmOp &amp;amp; 0xFFFF0000) != 0)&lt;br /&gt;
  InsertLoad32Immediate(...);&lt;br /&gt;
...&lt;br /&gt;
  MI-&amp;gt;eraseFromParent();&lt;br /&gt;
  return BB;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void InsertLoad32Immediate (...) {&lt;br /&gt;
 BuildMI(*BB, *MI, *DL, TII-&amp;gt;get(NaplesPU::MOVEIHSI))&lt;br /&gt;
         .addReg(DestReg, RegState::Define)&lt;br /&gt;
         .addImm(((Immediate &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF));&lt;br /&gt;
BuildMI(*BB, *MI, *DL, TII-&amp;gt;get(NaplesPU::MOVEILSI))&lt;br /&gt;
        .addReg(DestReg)&lt;br /&gt;
        .addImm((Immediate &amp;amp; 0xFFFF));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Frame Lowering ===&lt;br /&gt;
This section focuses on the definition of information about the stack frame layout on the target. &lt;br /&gt;
For this purpose, LLVM provides a target-independent interface, defined in ''TargetFrameLowering'', that has to be implemented for the target platform. It holds several pieces of information such as the direction of stack growth, the known stack alignment on entry to each function, and the offset to the local area.&lt;br /&gt;
&lt;br /&gt;
The custom platform is provided of a down-growing stack, 64-bit aligned. The specific implementation of the interface ''TargetFrameLowering'' is defined in the file [[NaplesPUFrameLowering.cpp]], and it includes the development of the following functions:&lt;br /&gt;
&lt;br /&gt;
* ''emitPrologue'' and ''emitEpilogue'', used to add the prologue and the epilogue code to a function, in terms of stack managing.&lt;br /&gt;
* ''eliminateCallFramePseudoInstr'' is the function devolved to replace the IR Call-Frame composed by pseudo-instructions with the target-specific one.&lt;br /&gt;
* ''hasReservedCallFrame'' is a boolean function that is used to check whether the prologue inserter should reserve stack space or not. &lt;br /&gt;
* ''hasFP'' is a boolean function that returns true if the specified function should have a dedicated frame pointer register. &lt;br /&gt;
* ''determineCalleeSaves'' determines which of ''CalleeSavedRegs'' should be actually saved.&lt;br /&gt;
&lt;br /&gt;
=== Code Emission Support ===&lt;br /&gt;
The code emission phase starts with the ''AsmPrinter'' pass. The core of this pass is the ''EmitInstruction'' function, that requires an ''MachineInstr'' object as input and transforms it in a ''MCInst'' instance. This transformation is done by using the ''Lower'' method, defined in [[NaplesPUMCInstLower.cpp]]. The MCInst instances generated are sent to the ''MCStreamer'', that can switch between two different ways: the generation of the binary target-specific code or the generation of the assembly code by using the ''MCObjectStreamer'' object in the first case and the ''MCAsmStreamer'' one in the latter.&lt;br /&gt;
The target-specific behavior is implemented in the class [[NaplesPUInstPrinter.cpp]] to handle the assembly code generation and in the class [[NaplesPUMCCodeEmitter.cpp]] to handle the binary code generation.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=Nu%2B_LLVM_Documentation&amp;diff=2103</id>
		<title>Nu+ LLVM Documentation</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=Nu%2B_LLVM_Documentation&amp;diff=2103"/>
				<updated>2019-06-21T14:37:29Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: Francesco moved page Nu+ LLVM Documentation to NaplesPU LLVM Documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[NaplesPU LLVM Documentation]]&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	<entry>
		<id>http://www.naplespu.com/doc/index.php?title=NaplesPU_LLVM_Documentation&amp;diff=2100</id>
		<title>NaplesPU LLVM Documentation</title>
		<link rel="alternate" type="text/html" href="http://www.naplespu.com/doc/index.php?title=NaplesPU_LLVM_Documentation&amp;diff=2100"/>
				<updated>2019-06-21T14:37:13Z</updated>
		
		<summary type="html">&lt;p&gt;Francesco: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The main task of the backend is to generate NPU assembly code from the LLVM IR obtained by the Clang frontend. It also handles object representation of classes needed to create the assembler and the disassembler.&lt;br /&gt;
The NPU backend is contained in the '''NaplesPU''' folder under &amp;quot;compiler/lib/Target&amp;quot; directory. It contains several files, each implementing a specific class of the LLVM Framework.&lt;br /&gt;
&lt;br /&gt;
An LLVM backend is constructed on two types of file, C++ and TableGen source files. Refer to section [[#TableGen | TableGen]] to get a detailed explanation of the latters.&lt;br /&gt;
&lt;br /&gt;
== Required reading ==&lt;br /&gt;
Before working on LLVM, you should be familiar with some things. In particular: &lt;br /&gt;
# [https://en.wikipedia.org/wiki/Basic_block '''Basic Blocks''']&lt;br /&gt;
# [https://en.wikipedia.org/wiki/Static_single_assignment_form '''SSA''' (Static Single Assignment) form]&lt;br /&gt;
# [https://en.wikipedia.org/wiki/Abstract_syntax_tree '''AST''' (Abstract Syntax tree)] &lt;br /&gt;
# [https://en.wikipedia.org/wiki/Directed_acyclic_graph '''DAG''' Direct Acyclic Graph].&lt;br /&gt;
&lt;br /&gt;
In addition to general aspects about compilers, it is recommended to review the following topics:&lt;br /&gt;
#[http://www.aosabook.org/en/llvm.html '''LLVM architecture''']&lt;br /&gt;
#[http://llvm.org/docs/LangRef.html '''LLVM Intermediate Representation'''] &lt;br /&gt;
&lt;br /&gt;
See the following textbook for other information [http://books.tarsoit.com/Getting%20Started%20with%20LLVM%20Core%20Libraries.pdf Getting Started with LLVM Core Libraries] and [https://github.com/iBreaker/book/blob/master/LLVM%20Cookbook.pdf LLVM Cookbook].&lt;br /&gt;
&lt;br /&gt;
See also [https://eli.thegreenplace.net/2012/11/24/life-of-an-instruction-in-llvm this article] to get an overview of the main CodeGenerator phases.&lt;br /&gt;
&lt;br /&gt;
== TableGen ==&lt;br /&gt;
&lt;br /&gt;
TableGen is a record-oriented language used to describe the target-specific information. It is written by the LLVM team in order to simplify the back-end development and to avoid potential code redundancy. For example, by using TableGen, if some feature of the target-specific register file changes, you do not need to modify different files wherever the register appears but you need only to modify the ''.td'' file that contains its definition. Actually, the TableGen is used to define instruction formats, instructions, registers, pattern-matching DAGs, instruction selection matching order, calling conventions, and target platform properties.&lt;br /&gt;
&lt;br /&gt;
For other information, check the [http://llvm.org/docs/TableGen/index.html TableGen Documentation]&lt;br /&gt;
&lt;br /&gt;
== Backend Description ==&lt;br /&gt;
&lt;br /&gt;
This section shows how is implemented the backend support for NPU within LLVM.&lt;br /&gt;
&lt;br /&gt;
=== Target Definition ===&lt;br /&gt;
&lt;br /&gt;
The target-specific information is explained in TableGen files. The custom target is defined by creating a new [[NaplesPU.td]] file,  in which the target itself is described. This file contains the implementation of the target-independent interfaces provided by ''Target.td''. Implementations are done by using the class inheritance mechanism.&lt;br /&gt;
&lt;br /&gt;
The code below is the ''Target'' class definition that should be implemented in [[NaplesPU.td]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class Target {&lt;br /&gt;
  InstrInfo InstructionSet;&lt;br /&gt;
  list&amp;lt;AsmParser&amp;gt; AssemblyParsers = [DefaultAsmParser];&lt;br /&gt;
  list&amp;lt;AsmParserVariant&amp;gt; AssemblyParserVariants = [DefaultAsmParserVariant];&lt;br /&gt;
  list&amp;lt;AsmWriter&amp;gt; AssemblyWriters = [DefaultAsmWriter];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This file should also include the other defined ''.td'' target-related files. The target definition is done as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;def : Processor&amp;lt;&amp;quot;naplespu&amp;quot;, NoItineraries, []&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ''Processor'' is a class defined in ''Target.td'':&lt;br /&gt;
&amp;lt;code&amp;gt;class Processor&amp;lt;string n, ProcessorItineraries pi, list&amp;lt;SubtargetFeature&amp;gt; f&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
* ''n'' is the chipset name, used in the command line option ''-mcpu'' to determine the appropriate chip.&lt;br /&gt;
* ''p'' is the processor itinerary, as described in the theoretical description of the LLVM ''instruction scheduling'' phase. ''NoItinerary'' means that no itinerary is defined.&lt;br /&gt;
* ''f'' is a list of target features.&lt;br /&gt;
&lt;br /&gt;
=== Registers Definition ===&lt;br /&gt;
The target-specific registers are defined in [[NaplesPURegisterInfo.td]]. LLVM provides two ways to define a register, both of them declared in ''Target.td''. The first one is used to define a simple scalar register and follows the declaration below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class Register&amp;lt;string n, list&amp;lt;string&amp;gt; altNames = []&amp;gt;&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
where ''n'' is the register name, while ''altNames'' is a list of register alternative names. &lt;br /&gt;
&lt;br /&gt;
The second method to define a register is to inherit from the class declared below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class RegisterWithSubRegs&amp;lt;string n, list&amp;lt;Register&amp;gt; subregs&amp;gt; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This second way is used when it is required to define a register that is a collection of ''n'' sub-registers.&lt;br /&gt;
There is also a third way to define registers. It consists of defining a ''super-register'', that is a pseudo-register resulting of the combination of other sub-registers. It is useful when there is no architectural support for larger registers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class RegisterTuples&amp;lt;list&amp;lt;SubRegIndex&amp;gt; Indices, list&amp;lt;dag&amp;gt; Regs&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, the following code is the declaration of the register class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class NaplesPUGPRReg&amp;lt;string n&amp;gt; : Register &amp;lt;n&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, registers can be instantiated as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
foreach i = 0-57 in {&lt;br /&gt;
    def S#i : NaplesPUGPRReg&amp;lt;&amp;quot;s&amp;quot;#i&amp;gt;, DwarfRegNum&amp;lt;[i]&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
def SP_REG : NaplesPUGPRReg&amp;lt;&amp;quot;sp&amp;quot;&amp;gt;, DwarfRegNum&amp;lt;[61]&amp;gt;; //stack pointer&lt;br /&gt;
...&lt;br /&gt;
foreach i = 0-63 in {&lt;br /&gt;
    def V#i : NaplesPUGPRReg&amp;lt;&amp;quot;v&amp;quot;#i&amp;gt;, DwarfRegNum&amp;lt;[!add(i, 64)]&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The instantiation reflects the custom target hardware architecture, with a set of scalar registers and a set of vectorial ones.&lt;br /&gt;
Each register inherits also from the''DwarfRegNum'' assigning to it an incremental number. This is useful for the internal identification of registers, consistent with the ''DWARF'' standard.&lt;br /&gt;
&lt;br /&gt;
Now that registers are defined they must belong to classes in order to define the allocation of them.&lt;br /&gt;
&lt;br /&gt;
LLVM provides the ''RegisterClass'' defined as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class RegisterClass&amp;lt;string namespace, list&amp;lt;ValueType&amp;gt; regTypes, int alignment, dag regList&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in which:&lt;br /&gt;
&lt;br /&gt;
* ''namespace'' is the namespace associate to it;&lt;br /&gt;
* ''regTypes'' is a list of ''ValueType'' values indicating the types of variables that can be allocated into them;&lt;br /&gt;
* ''alignment'' is the alignment associated to the registers in the ''RegisterClass'';&lt;br /&gt;
* ''regList'' is the list of registers that belong to the class. Since the parameter type is ''dag'', TableGen provides operands to define a set of registers in terms of a set of operators.&lt;br /&gt;
&lt;br /&gt;
For example, to match our target features it is necessary to define two classes:&lt;br /&gt;
* GPR32, that is the abstraction of 32-bit wide scalar registers;&lt;br /&gt;
* VR512W, that are the abstraction of 512-bit wide vectorial registers; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def GPR32 : RegisterClass&amp;lt;&amp;quot;NaplesPU&amp;quot;, [i32, f32, i64, f64], 32, (add (sequence &amp;quot;S%u&amp;quot;, 0, 57),&lt;br /&gt;
  TR_REG, MR_REG, FP_REG, SP_REG, RA_REG, PC_REG)&amp;gt;;&lt;br /&gt;
def VR512W : RegisterClass&amp;lt;&amp;quot;NaplesPU&amp;quot;, [v16i32, v16f32, v16i8, v16i16], 512, (sequence &amp;quot;V%u&amp;quot;, 0, 63)&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling Convention ===&lt;br /&gt;
&lt;br /&gt;
This section shows how to define the ''calling convention'', that is how ''parameters'' are passed to sub-functions, and how the ''return value'' is sent back to the caller. &lt;br /&gt;
&lt;br /&gt;
The calling convention is defined in the [[NaplesPUCallingConv.td]] by using the classes defined in the ''TargetCallingConv.td'' file. &lt;br /&gt;
&lt;br /&gt;
In our purposes, it's required to define the calling convention in terms of the registers used to pass the arguments to the callee. &lt;br /&gt;
LLVM provides the ''CallingConv'' class defined below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class CallingConv&amp;lt;list&amp;lt;CCAction&amp;gt; actions&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This class requires a list of ''CCAction''. ''TargetCallingConv.td'' contains a set of ''CCAction'' derived classes that must be used to define the sub-function calling behaviour.&lt;br /&gt;
&lt;br /&gt;
The calling convention for the custom target device is defined by using the first ''eight'' registers, and then the stack for the remaining parameters. It means that for 32-bit variables, they are passed to the callee by using the registers Si, where i = 0..7.&lt;br /&gt;
The same schema is adopted for vectorial variables. &lt;br /&gt;
&lt;br /&gt;
The calling convention should also take care of the passing of type that is not natively supported by the target. In this case, the solution adopted is the type promotion. The mechanism is simple: it consists of promoting the unsupported type to a supported one. It can be easily implemented by only using the ''CCAction'' classes provided by LLVM.&lt;br /&gt;
By using the just described approach, ''i1, i8, i16'' are promoted to ''i32'' while ''v16i8, v16i16'' are promoted to ''v16i32''. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def CC_NaplesPU : CallingConv&amp;lt;[&lt;br /&gt;
  CCIfType&amp;lt;[i1, i8, i16], CCPromoteToType&amp;lt;i32&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[v16i8, v16i16], CCPromoteToType&amp;lt;v16i32&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[i32, f32], CCAssignToReg&amp;lt;[S0, S1, S2, S3, S4, S5, S6, S7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfNotVarArg&amp;lt;CCIfType&amp;lt;[v16i32, v16f32], CCAssignToReg&amp;lt;[V0, V1, V2, V3, V4, V5, V6, V7]&amp;gt;&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[i32, f32], CCAssignToStack&amp;lt;4, 4&amp;gt;&amp;gt;,&lt;br /&gt;
  CCIfType&amp;lt;[v16i32, v16f32], CCAssignToStack&amp;lt;64, 64&amp;gt;&amp;gt;&lt;br /&gt;
]&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The calling convention for NPU in terms of results returning mechanism is realized by passing them in the first six registers. &lt;br /&gt;
&lt;br /&gt;
It could be also possible that the return type does not correspond to any native target type. The solution is ''promoting''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def RetCC_NaplesPU32 : CallingConv&amp;lt;[&lt;br /&gt;
CCIfType&amp;lt;[i1, i8, i16], CCPromoteToType&amp;lt;i32&amp;gt;&amp;gt;,&lt;br /&gt;
CCIfType&amp;lt;[i32, f32], CCAssignToReg&amp;lt;[S0, S1, S2, S3, S4, S5]&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LLVM also provides a mechanism to define the registers that the callee must save before starting the function execution. The mechanism consists in defining an instance of the class ''CalleeSavedRegs'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class CalleeSavedRegs&amp;lt;dag saves&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ''saves'' is the list of registers to be saved. &lt;br /&gt;
&lt;br /&gt;
For example, in NPU, the callee saved registers are defined as follows:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code&amp;gt;def NaplesPUCSR : CalleeSavedRegs&amp;lt;(add (sequence &amp;quot;S%u&amp;quot;, 50, 57), MR_REG, FP_REG, RA_REG, (sequence &amp;quot;V%u&amp;quot;, 56, 63))&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ISA Support ===&lt;br /&gt;
&lt;br /&gt;
In order to define the LLVM support for NPU, the next step is to handle the target-specific code generation by implementing its ''ISA'' (Instruction Set Architecture) in LLVM. &lt;br /&gt;
In order to describe it, TableGen provides the class ''Instruction'' located in ''Target.td''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class Instruction {&lt;br /&gt;
  string Namespace = &amp;quot;&amp;quot;;&lt;br /&gt;
  dag OutOperandList;       &lt;br /&gt;
  dag InOperandList;     &lt;br /&gt;
  string AsmString = &amp;quot;&amp;quot;; &lt;br /&gt;
  list&amp;lt;dag&amp;gt; Pattern;&lt;br /&gt;
  list&amp;lt;Register&amp;gt; Uses = []; &lt;br /&gt;
  list&amp;lt;Register&amp;gt; Defs = [];&lt;br /&gt;
  list&amp;lt;Predicate&amp;gt; Predicates = [];&lt;br /&gt;
  int Size = 0;&lt;br /&gt;
  bit isReturn     = 0;     &lt;br /&gt;
  bit isBranch     = 0;    &lt;br /&gt;
  bit isPseudo     = 0;    &lt;br /&gt;
  bit isCodeGenOnly = 0;&lt;br /&gt;
  bit isAsmParserOnly = 0;&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As it is clear, the ''Instruction'' class provides a lot of member variable to describe an instruction. The following are a subset that is used for our purposes:&lt;br /&gt;
&lt;br /&gt;
* ''OutOperandList'' is the set of output operands of the instruction, defined as of ''dag'' type.&lt;br /&gt;
* ''InOperandList'' is the set of input operands of the instruction, defined as of ''dag'' type.&lt;br /&gt;
* ''AsmString'' is the''.s'' format to print the instruction with.&lt;br /&gt;
* ''isReturn'' defines the instruction as a ''return'' one.&lt;br /&gt;
* ''isBranch'' defines the instruction as a ''branch'' one, that is, it breaks the sequential control flow.&lt;br /&gt;
* ''isPseudo'' defines the instruction as a ''pseudo'' one, or rather an instruction for which there is not a corresponding machine instruction.&lt;br /&gt;
* ''isCodeGenOnly'', ''isAsmParserOnly'' and ''usesCustomInserter'' are also defining a pseudo-instruction, but with different behaviour. The first field is describing a pseudo-instruction that is used for CodeGen modeling purposes while the second one is describing a pseudo-instruction used by the assembler parser. The third one tells that the pseudo-instruction needs to be manually lowered to a machine instruction.&lt;br /&gt;
* ''Uses'' and ''Defs'' are lists of registers that are respectively read and written by the instruction. &lt;br /&gt;
* ''Predicates'' are logical expressions that must be checked in the Instruction Selection phase.&lt;br /&gt;
* ''Pattern'' is a list of ''dag'', each of them explains a DAG Pattern for the instruction used by the instruction selector to turn a set of ''SelectionDAG}'' nodes in the corresponding target-specific instruction. &lt;br /&gt;
&lt;br /&gt;
In order to handle the target platform ISA complexity it has been adapted a hierarchical schema of classes, each one represents a specific instruction format. &lt;br /&gt;
&lt;br /&gt;
First of all it is defined a generic format for the target-specific instruction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class InstNaplesPU&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern&amp;gt;&lt;br /&gt;
          : Instruction {&lt;br /&gt;
  field bits&amp;lt;32&amp;gt; Inst;&lt;br /&gt;
  let Namespace = &amp;quot;MyTarget&amp;quot;;&lt;br /&gt;
  let Size = 4;&lt;br /&gt;
  dag OutOperandList = outs;&lt;br /&gt;
  dag InOperandList = ins;&lt;br /&gt;
  let AsmString   = asmstr;&lt;br /&gt;
  let Pattern = pattern;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All instruction classes are inherited by the one above, specifying what the instruction bits are representing. Since the target supports different types of instruction format, for each of them is defined as a different class. Each class is then defined in terms of other sub-classes. For example, it may be useful to analyze the ''R'' format, that is the instruction format used to handle logical and arithmetic operations and memory operations. &lt;br /&gt;
By analyzing the instruction type it may be useful to distinguish among different sub-types, by structuring a hierarchy.&lt;br /&gt;
&lt;br /&gt;
[[File:Formats_hierarchy.jpg|This picture shows how the classes are inherited from the FR class.]]&lt;br /&gt;
&lt;br /&gt;
In this way, we shall define a set of classes implementing the hierarchy exposed, from the root, that represents the most generic R-type instruction, to leaves. Since the instruction format requires a set of ''FMT'' bits, it is also necessary to define a class to handle them:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class Fmt&amp;lt;bit val&amp;gt; {&lt;br /&gt;
  bit Value = val;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The root class is defined as the most general class of the hierarchy. For this reason, the second source operand is not defined. The derived class, implementing the two-operand R-type instruction, will properly set the related field. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class FR&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : InstNaplesPU&amp;lt;outs, ins, asmstr, pattern&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; dst;&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src0;&lt;br /&gt;
  let Inst{31-30} = 0;&lt;br /&gt;
  let Inst{29-24} = opcode;&lt;br /&gt;
  let Inst{23-18} = dst;&lt;br /&gt;
  let Inst{17-12} = src0;&lt;br /&gt;
  let Inst{5} = 0; //unused&lt;br /&gt;
  let Inst{4} = 0; //No 64-bit support&lt;br /&gt;
  let Inst{3} = fmt2.Value;&lt;br /&gt;
  let Inst{2} = fmt1.Value;&lt;br /&gt;
  let Inst{1} = fmt0.Value;&lt;br /&gt;
  let Inst{0} = 1;&lt;br /&gt;
  let Uses=[MR_REG];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class FR_TwoOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR&amp;lt;outs, ins, asmstr, pattern, opcode, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
  bits &amp;lt;6&amp;gt; src1;&lt;br /&gt;
  let Inst{11-6} = src1;&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class FR_OneOp&amp;lt;dag outs, dag ins, string asmstr, list&amp;lt;dag&amp;gt; pattern, bits&amp;lt;6&amp;gt; opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0&amp;gt;&lt;br /&gt;
   : FR_TwoOp&amp;lt;outs, ins, asmstr, pattern, opcode, fmt2, fmt1, fmt0&amp;gt; {&lt;br /&gt;
   let Inst{11-6} = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code above is showing the implementation of the classes hierarchy illustrated above. &lt;br /&gt;
All the other instruction format are implementing by using the same method.&lt;br /&gt;
&lt;br /&gt;
However, the class definition method is not a flexible way to explain the commonalities among more than two definition instances. As a solution, LLVM provides the ''multiclass'' construct. For example, if an arithmetic instruction is designed to work both with an immediate value or two registers, the class construct forces to have implementation as described below. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
class rrinst&amp;lt;int opc, string asmstr&amp;gt;&lt;br /&gt;
  : inst&amp;lt;opc, !strconcat(asmstr, &amp;quot; $dst, $src1, $src2&amp;quot;),&lt;br /&gt;
         (ops GPR:$dst, GPR:$src1, GPR:$src2)&amp;gt;;&lt;br /&gt;
class riinst&amp;lt;int opc, string asmstr&amp;gt;&lt;br /&gt;
  : inst&amp;lt;opc, !strconcat(asmstr, &amp;quot; $dst, $src1, $src2&amp;quot;),&lt;br /&gt;
         (ops GPR:$dst, GPR:$src1, Imm:$src2)&amp;gt;;&lt;br /&gt;
def ADD_rr : rrinst&amp;lt;0b111, &amp;quot;add&amp;quot;&amp;gt;;&lt;br /&gt;
def ADD_ri : riinst&amp;lt;0b111, &amp;quot;add&amp;quot;&amp;gt;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The usage of the class construct in this context is quietly unfeasible. Differently, below is showed how clean is the approach using the ''multiclass'' construct.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
multiclass ri_inst&amp;lt;int opc, string asmstr&amp;gt; {&lt;br /&gt;
  def _rr : inst&amp;lt;opc, !strconcat(asmstr, &amp;quot; $dst, $src1, $src2&amp;quot;),&lt;br /&gt;
                 (ops GPR:$dst, GPR:$src1, GPR:$src2)&amp;gt;;&lt;br /&gt;
  def _ri : inst&amp;lt;opc, !strconcat(asmstr, &amp;quot; $dst, $src1, $src2&amp;quot;),&lt;br /&gt;
                 (ops GPR:$dst, GPR:$src1, Imm:$src2)&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
defm ADD : ri_inst&amp;lt;0b111, &amp;quot;add&amp;quot;&amp;gt;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ''multiclass'' construct is used to handle different register types for arithmetic operations. Therefore, despite defining several classes, one for each combination of scalar and vectorial registers as source operands, the usage of the ''multiclass'' construct is the best solution to do it. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
multiclass FArithInt_TwoOp&amp;lt;string operator, SDNode OpNode, bits&amp;lt;6&amp;gt; opcode&amp;gt; {&lt;br /&gt;
  def SSS_32 : FR_TwoOp&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$src0, GPR32:$src1),&lt;br /&gt;
    operator # &amp;quot;_i32 $dst, $src0, $src1&amp;quot;,&lt;br /&gt;
    [(set i32:$dst, (OpNode i32:$src0, i32:$src1))],&lt;br /&gt;
    opcode,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S,&lt;br /&gt;
    Fmt_S&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pattern Recognition ===&lt;br /&gt;
&lt;br /&gt;
The ''Instruction Selection'' phase tries to substitute the IR instruction with the target-specific one. This pass is structured in two ways implemented in ''Select()'' method of the ''SelectionDAGISel''  class: the first way tries to find an instruction matching by looking at the target description provided by the compiled TableGen files, while the second way is looking to a custom code matching defined by the user. &lt;br /&gt;
&lt;br /&gt;
Consequently, it is useful to define instruction patterns in order to help the ''Select'' method to find a proper match. TableGen defines a set of classes that are used to declare a pattern. &lt;br /&gt;
&lt;br /&gt;
For example, an important concept implemented is the ''Pattern Fragment'', that is a reusable chunk of DAG that matches specific nodes. LLVM provides few implementation of the mentioned class, starting from the ''PatFrag'', that is the most general class, to ''OutPatFrag'', ''PatLeaf'' and ''ImmLeaf'' inherited from the first one. &lt;br /&gt;
&lt;br /&gt;
The''PatFrag'' definition is showed below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class PatFrag&amp;lt;dag ops, dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm&amp;gt; : SDPatternOperator&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
* ''ops'' represents the input operands;&lt;br /&gt;
* ''frag'' is the fragment to be matched;&lt;br /&gt;
* ''pred'' is the predicate to be satisfied in order to apply the transformation;&lt;br /&gt;
* ''xform'' is the transformation to be applied if all the previous points are fulfilled.&lt;br /&gt;
&lt;br /&gt;
In NaplesPU, the ''PatFrag'' class is used to handle the ''store'' operations, in terms of the address space they refer to. In our purposes, it is required to define a store operation in the global memory if and only if it is satisfied with a condition on the address space identification number. Otherwise, the memory operation refers to the ''scratchpad'' address space.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def MemStore : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                       (store node:$val, node:$ptr), [{&lt;br /&gt;
               if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() != 77)&lt;br /&gt;
                  return !cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;isTruncatingStore();&lt;br /&gt;
               else&lt;br /&gt;
                  return false;}]&amp;gt;;&lt;br /&gt;
def ScratchpadStore : PatFrag&amp;lt;(ops node:$val, node:$ptr),&lt;br /&gt;
                              (store node:$val, node:$ptr), [{&lt;br /&gt;
               if(cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;getAddressSpace() == 77)&lt;br /&gt;
                 return !cast&amp;lt;StoreSDNode&amp;gt;(N)-&amp;gt;isTruncatingStore();&lt;br /&gt;
               else&lt;br /&gt;
                 return false;}]&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''PatLeaf'' is the a ''PatFrag'' sub-class, deprived of the transformation and the pattern parameters, used, for example, to handle the ''immediate'' values transformation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def simm16 : PatLeaf&amp;lt;(imm), [{ return isInt&amp;lt;16&amp;gt;(N-&amp;gt;getSExtValue()); }]&amp;gt;;&lt;br /&gt;
def simm9 : PatLeaf&amp;lt;(imm), [{ return isInt&amp;lt;9&amp;gt;(N-&amp;gt;getSExtValue()); }]&amp;gt;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern exposed is used to recognise if the immediate is 9-bit wide or 16-bit wide. &lt;br /&gt;
LLVM also provides a class that is used to define more complex patterns than the ones explained above. It is typically used to handle the ''addressing modes''. &lt;br /&gt;
The described behaviour is implemented in the class ''ComplexPattern'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class ComplexPattern&amp;lt;ValueType ty, int numops, string fn, list&amp;lt;SDNode&amp;gt; roots = [], list&amp;lt;SDNodeProperty&amp;gt; props = []&amp;gt; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
* ''ty'' is the type associated to the pattern;&lt;br /&gt;
* ''numops'' is the number of operands returned by the function;&lt;br /&gt;
* ''n'' is the name of the function;&lt;br /&gt;
* ''roots'' is the list of possible \textit{root nodes} of the sub-DAG to match;&lt;br /&gt;
* ''props'' is a list of possible predicates to match. &lt;br /&gt;
&lt;br /&gt;
As mentioned above, this pattern is usually used to handle the addressing modes. In our purpose, the pattern is used to evaluate the address as ''base plus offset''. For this reason, it is necessary to define a proper function in the ''Select()'' method [[NaplesPUISelDAGToDAG.cpp]] file.&lt;br /&gt;
&lt;br /&gt;
The following line shows how to define a ''ComplexPattern'' instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;def ADDRri:ComplexPattern&amp;lt;iPTR, 2, &amp;quot;SelectADDRri&amp;quot;, [frameindex], []&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern above calls the method ''SelectADDRri'' defined in the [[NaplesPUISelDAGToDAG.cpp]] when an SDNode is of ''iPTR'' type.&lt;br /&gt;
&lt;br /&gt;
=== Instructions definition ===&lt;br /&gt;
This section describes how to use the formats defined in [[NaplesPUInstrFormats.td]] to instantiate the target-specific instructions. &lt;br /&gt;
Because of the instruction formats definition described before, the target-specific ISA can be realized by simply instantiating the formats themselves. &lt;br /&gt;
&lt;br /&gt;
For instance, the ''ADD'' instruction is of the ''arithmetic'' format, that is implemented by using the ''multiclass'' construct. As a consequence, the instantiation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; defm ADD:FArithInt_TwoOp&amp;lt;&amp;quot;add&amp;quot;, add, 4&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other arithmetic instructions are implemented in a similar way as above.&lt;br /&gt;
Thanks to the ''multiclass'' construct a single definition instantiates scalar and vector variants of the ''ADD'' instruction.&lt;br /&gt;
&lt;br /&gt;
Instruction definition is located in [[NaplesPUInstrInfo.td]].&lt;br /&gt;
 &lt;br /&gt;
There are some cases in which the TableGen generated outputs are not enough to produce a legalized DAG composed of only machine instruction nodes. In these cases could be useful to define a pattern that helps the instruction selection algorithm to find a match. Beyond the ''PatFrag'' class, LLVM provides an explicit way to force a pattern matching through the class ''Pat'', defined as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; class Pat&amp;lt;dag pattern, dag result&amp;gt; : Pattern&amp;lt;pattern, [result]&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance, consider the frontend intrinsic ''int_npu_vector_mix32''. It is converted in a target-specific node through the ''Pat'' class, as explained below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; def : Pat&amp;lt;(int_npu_vector_mixf32 v16f32:$src0, v16f32:$oldvalue),  (MOVE_VV_M_32 v16f32:$src0, v16f32:$oldvalue)&amp;gt;; } &amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
As a result of the pattern application, the considered node is transformed into ''MOVE_VV_M_32'' that is a target-specific node.&lt;br /&gt;
 &lt;br /&gt;
Even though the use of ''Pat'' s an easy-to-apply solution to help the instruction selector, its power is limited to simple substitutions. &lt;br /&gt;
More complex behaviors have to be managed manually in the ''Lowering'' Pass.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Selection Lowering ===&lt;br /&gt;
&lt;br /&gt;
Because the TableGen description is not enough to have a full substitution of target-dependent nodes, LLVM provides a ''C++'' file to implement the lowering pass, that [[NaplesPUISelLowering.cpp]].&lt;br /&gt;
In our purpose, the lowering mainly concerns the ''pseudo-instructions'' defined in [[NaplesPUInstrInfo.td]]. Recall that a pseudo-instruction is a special instruction that does not map to any machine code. For example, it is helpful to analyze how is managed the ''load'' operation associated to a 32-bit immediate value.&lt;br /&gt;
The 32-bit instruction format allows the ''move'' operation for an immediate operand that is at most 16-bit wide. To handle wider immediate operands it is necessary to find a solution. &lt;br /&gt;
By looking at [[NaplesPUInstrInfo.td]], the mentioned operation, named ''LoadI32'', is defined as a pseudo-instruction with ''usesCustomInserter'' bit set, as showed below. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
let usesCustomInserter = 1 in {&lt;br /&gt;
  def LoadI32 : Pseudo&amp;lt;&lt;br /&gt;
    (outs GPR32:$dst),&lt;br /&gt;
    (ins GPR32:$val),&lt;br /&gt;
    [(set i32:$dst, (i32 imm:$val))]&amp;gt;;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LLVM APIs are designed to deal with DAG nodes. To handle the ''Load32I'' operation, ''MOVEIH'' and ''MOVEIL'' instructions are used. For this reason, the 32-bit value is split into two sub-values, each one of 16-bit wide that can be used to build the machine instruction nodes. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
MachineBasicBlock *&lt;br /&gt;
NaplesPUTargetLowering::EmitInstrWithCustomInserter(MachineInstr &amp;amp;MI,&lt;br /&gt;
                                                 MachineBasicBlock *BB) const {&lt;br /&gt;
  switch (MI.getOpcode()) {&lt;br /&gt;
  case NaplesPU::LoadI32:&lt;br /&gt;
  	return EmitLoadI32(&amp;amp;MI, BB);&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ''LoadI32'' is split into two machine instruction, one that uses the MOVEIH instruction and the other that uses the MOVEIL instruction, as the code below explains.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
MachineBasicBlock* EmitLoadI32(...) const {&lt;br /&gt;
  DebugLoc DL = MI-&amp;gt;getDebugLoc();&lt;br /&gt;
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();&lt;br /&gt;
  int64_t ImmOp = MI-&amp;gt;getOperand(1).getImm(); &lt;br /&gt;
if((ImmOp &amp;amp; 0xFFFF0000) != 0)&lt;br /&gt;
  InsertLoad32Immediate(...);&lt;br /&gt;
...&lt;br /&gt;
  MI-&amp;gt;eraseFromParent();&lt;br /&gt;
  return BB;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void InsertLoad32Immediate (...) {&lt;br /&gt;
 BuildMI(*BB, *MI, *DL, TII-&amp;gt;get(NaplesPU::MOVEIHSI))&lt;br /&gt;
         .addReg(DestReg, RegState::Define)&lt;br /&gt;
         .addImm(((Immediate &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF));&lt;br /&gt;
BuildMI(*BB, *MI, *DL, TII-&amp;gt;get(NaplesPU::MOVEILSI))&lt;br /&gt;
        .addReg(DestReg)&lt;br /&gt;
        .addImm((Immediate &amp;amp; 0xFFFF));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Frame Lowering ===&lt;br /&gt;
This section focuses on the definition of information about the stack frame layout on the target. &lt;br /&gt;
For this purpose, LLVM provides a target-independent interface, defined in ''TargetFrameLowering'', that has to be implemented for the target platform. It holds several pieces of information such as the direction of stack growth, the known stack alignment on entry to each function, and the offset to the local area.&lt;br /&gt;
&lt;br /&gt;
The custom platform is provided of a down-growing stack, 64-bit aligned. The specific implementation of the interface ''TargetFrameLowering'' is defined in the file [[NaplesPUFrameLowering.cpp]], and it includes the development of the following functions:&lt;br /&gt;
&lt;br /&gt;
* ''emitPrologue'' and ''emitEpilogue'', used to add the prologue and the epilogue code to a function, in terms of stack managing.&lt;br /&gt;
* ''eliminateCallFramePseudoInstr'' is the function devolved to replace the IR Call-Frame composed by pseudo-instructions with the target-specific one.&lt;br /&gt;
* ''hasReservedCallFrame'' is a boolean function that is used to check whether the prologue inserter should reserve stack space or not. &lt;br /&gt;
* ''hasFP'' is a boolean function that returns true if the specified function should have a dedicated frame pointer register. &lt;br /&gt;
* ''determineCalleeSaves'' determines which of ''CalleeSavedRegs'' should be actually saved.&lt;br /&gt;
&lt;br /&gt;
=== Code Emission Support ===&lt;br /&gt;
The code emission phase starts with the ''AsmPrinter'' pass. The core of this pass is the ''EmitInstruction'' function, that requires an ''MachineInstr'' object as input and transforms it in a ''MCInst'' instance. This transformation is done by using the ''Lower'' method, defined in [[NaplesPUMCInstLower.cpp]]. The MCInst instances generated are sent to the ''MCStreamer'', that can switch between two different ways: the generation of the binary target-specific code or the generation of the assembly code by using the ''MCObjectStreamer'' object in the first case and the ''MCAsmStreamer'' one in the latter.&lt;br /&gt;
The target-specific behavior is implemented in the class [[NaplesPUInstPrinter.cpp]] to handle the assembly code generation and in the class [[NaplesPUMCCodeEmitter.cpp]] to handle the binary code generation.&lt;/div&gt;</summary>
		<author><name>Francesco</name></author>	</entry>

	</feed>