17593SbrutissoPull in r198533 from upstream llvm trunk (by Venkatraman Govindaraju):
211372Ssjohanss
37593Sbrutisso  [Sparc] Add initial implementation of MC Code emitter for sparc.
47593Sbrutisso
57593SbrutissoIntroduced here: http://svnweb.freebsd.org/changeset/base/262261
67593Sbrutisso
77593SbrutissoIndex: lib/Target/Sparc/SparcInstrInfo.td
87593Sbrutisso===================================================================
97593Sbrutisso--- lib/Target/Sparc/SparcInstrInfo.td
107593Sbrutisso+++ lib/Target/Sparc/SparcInstrInfo.td
117593Sbrutisso@@ -100,9 +100,14 @@ def MEMri : Operand<iPTR> {
127593Sbrutisso def TLSSym : Operand<iPTR>;
137593Sbrutisso 
147593Sbrutisso // Branch targets have OtherVT type.
157593Sbrutisso-def brtarget : Operand<OtherVT>;
167593Sbrutisso-def calltarget : Operand<i32>;
177593Sbrutisso+def brtarget : Operand<OtherVT> {
187593Sbrutisso+  let EncoderMethod = "getBranchTargetOpValue";
197593Sbrutisso+}
207593Sbrutisso 
217593Sbrutisso+def calltarget : Operand<i32> {
227593Sbrutisso+  let EncoderMethod = "getCallTargetOpValue";
237593Sbrutisso+}
247593Sbrutisso+
257593Sbrutisso // Operand for printing out a condition code.
2611372Ssjohanss let PrintMethod = "printCCOperand" in
277593Sbrutisso   def CCOp : Operand<i32>;
287593SbrutissoIndex: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
2911833Sctornqvi===================================================================
3011098Sdsamersoff--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
3111833Sctornqvi+++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
327663Sbrutisso@@ -1,6 +1,8 @@
3311372Ssjohanss add_llvm_library(LLVMSparcDesc
347725Ssjohanss+  SparcAsmBackend.cpp
357725Ssjohanss+  SparcMCAsmInfo.cpp
3611641Sdfazunen+  SparcMCCodeEmitter.cpp
377663Sbrutisso   SparcMCTargetDesc.cpp
387663Sbrutisso-  SparcMCAsmInfo.cpp
397663Sbrutisso   SparcMCExpr.cpp
407663Sbrutisso   SparcTargetStreamer.cpp
417663Sbrutisso   )
427663SbrutissoIndex: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
437663Sbrutisso===================================================================
447593Sbrutisso--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
4511641Sdfazunen+++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
467663Sbrutisso@@ -0,0 +1,131 @@
4711641Sdfazunen+//===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===//
487663Sbrutisso+//
497663Sbrutisso+//                     The LLVM Compiler Infrastructure
507663Sbrutisso+//
517663Sbrutisso+// This file is distributed under the University of Illinois Open Source
5211641Sdfazunen+// License. See LICENSE.TXT for details.
5311641Sdfazunen+//
5411641Sdfazunen+//===----------------------------------------------------------------------===//
5511641Sdfazunen+//
5611641Sdfazunen+// This file implements the SparcMCCodeEmitter class.
577593Sbrutisso+//
587593Sbrutisso+//===----------------------------------------------------------------------===//
5911372Ssjohanss+
6011372Ssjohanss+#define DEBUG_TYPE "mccodeemitter"
6111372Ssjohanss+#include "SparcMCTargetDesc.h"
6211372Ssjohanss+#include "MCTargetDesc/SparcFixupKinds.h"
6311372Ssjohanss+#include "llvm/MC/MCCodeEmitter.h"
648232Ssjiang+#include "llvm/MC/MCContext.h"
657663Sbrutisso+#include "llvm/MC/MCExpr.h"
667593Sbrutisso+#include "llvm/MC/MCInst.h"
677593Sbrutisso+#include "llvm/MC/MCRegisterInfo.h"
687593Sbrutisso+#include "llvm/ADT/Statistic.h"
6911372Ssjohanss+#include "llvm/Support/raw_ostream.h"
7011372Ssjohanss+
7111372Ssjohanss+using namespace llvm;
7211372Ssjohanss+
737663Sbrutisso+STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
747663Sbrutisso+
757663Sbrutisso+namespace {
767663Sbrutisso+class SparcMCCodeEmitter : public MCCodeEmitter {
7711372Ssjohanss+  SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
7811372Ssjohanss+  void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
7911372Ssjohanss+  MCContext &Ctx;
8011372Ssjohanss+
8111372Ssjohanss+public:
8211372Ssjohanss+  SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {}
8311372Ssjohanss+
8411372Ssjohanss+  ~SparcMCCodeEmitter() {}
8511641Sdfazunen+
8611372Ssjohanss+  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
8711372Ssjohanss+                         SmallVectorImpl<MCFixup> &Fixups) const;
8811641Sdfazunen+
8911372Ssjohanss+  // getBinaryCodeForInstr - TableGen'erated function for getting the
9011372Ssjohanss+  // binary encoding for an instruction.
9111372Ssjohanss+  uint64_t getBinaryCodeForInstr(const MCInst &MI,
9211372Ssjohanss+                                 SmallVectorImpl<MCFixup> &Fixups) const;
9311372Ssjohanss+
9411372Ssjohanss+  /// getMachineOpValue - Return binary encoding of operand. If the machine
9511372Ssjohanss+  /// operand requires relocation, record the relocation and return zero.
9611641Sdfazunen+  unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
9711372Ssjohanss+                             SmallVectorImpl<MCFixup> &Fixups) const;
9811372Ssjohanss+
9911372Ssjohanss+  unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
10011372Ssjohanss+                             SmallVectorImpl<MCFixup> &Fixups) const;
1017593Sbrutisso+  unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
1027593Sbrutisso+                             SmallVectorImpl<MCFixup> &Fixups) const;
10311372Ssjohanss+
10411372Ssjohanss+};
10511372Ssjohanss+} // end anonymous namespace
10611372Ssjohanss+
10711372Ssjohanss+MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
10811372Ssjohanss+                                              const MCRegisterInfo &MRI,
10911372Ssjohanss+                                              const MCSubtargetInfo &STI,
11011372Ssjohanss+                                              MCContext &Ctx) {
11111372Ssjohanss+  return new SparcMCCodeEmitter(Ctx);
11211372Ssjohanss+}
113+
114+void SparcMCCodeEmitter::
115+EncodeInstruction(const MCInst &MI, raw_ostream &OS,
116+                  SmallVectorImpl<MCFixup> &Fixups) const {
117+  unsigned Bits = getBinaryCodeForInstr(MI, Fixups);
118+
119+  // Output the constant in big endian byte order.
120+  for (unsigned i = 0; i != 4; ++i) {
121+    OS << (char)(Bits >> 24);
122+    Bits <<= 8;
123+  }
124+
125+  ++MCNumEmitted;  // Keep track of the # of mi's emitted.
126+}
127+
128+
129+unsigned SparcMCCodeEmitter::
130+getMachineOpValue(const MCInst &MI, const MCOperand &MO,
131+                  SmallVectorImpl<MCFixup> &Fixups) const {
132+
133+  if (MO.isReg())
134+    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
135+
136+  if (MO.isImm())
137+    return MO.getImm();
138+
139+  assert(MO.isExpr());
140+  const MCExpr *Expr = MO.getExpr();
141+  int64_t Res;
142+  if (Expr->EvaluateAsAbsolute(Res))
143+    return Res;
144+
145+  assert(0 && "Unhandled expression!");
146+  return 0;
147+}
148+
149+unsigned SparcMCCodeEmitter::
150+getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
151+                     SmallVectorImpl<MCFixup> &Fixups) const {
152+  const MCOperand &MO = MI.getOperand(OpNo);
153+  if (MO.isReg() || MO.isImm())
154+    return getMachineOpValue(MI, MO, Fixups);
155+
156+  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
157+                                   (MCFixupKind)Sparc::fixup_sparc_call30));
158+  return 0;
159+}
160+
161+unsigned SparcMCCodeEmitter::
162+getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
163+                  SmallVectorImpl<MCFixup> &Fixups) const {
164+  const MCOperand &MO = MI.getOperand(OpNo);
165+  if (MO.isReg() || MO.isImm())
166+    return getMachineOpValue(MI, MO, Fixups);
167+
168+  Sparc::Fixups fixup = Sparc::fixup_sparc_br22;
169+  if (MI.getOpcode() == SP::BPXCC)
170+    fixup = Sparc::fixup_sparc_br19;
171+
172+  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
173+                                   (MCFixupKind)fixup));
174+  return 0;
175+}
176+
177+#include "SparcGenMCCodeEmitter.inc"
178Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
179===================================================================
180--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
181+++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
182@@ -136,6 +136,18 @@ extern "C" void LLVMInitializeSparcTargetMC() {
183   TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target,
184                                           createSparcMCSubtargetInfo);
185 
186+  // Register the MC Code Emitter.
187+  TargetRegistry::RegisterMCCodeEmitter(TheSparcTarget,
188+                                        createSparcMCCodeEmitter);
189+  TargetRegistry::RegisterMCCodeEmitter(TheSparcV9Target,
190+                                        createSparcMCCodeEmitter);
191+
192+  //Register the asm backend.
193+  TargetRegistry::RegisterMCAsmBackend(TheSparcTarget,
194+                                       createSparcAsmBackend);
195+  TargetRegistry::RegisterMCAsmBackend(TheSparcV9Target,
196+                                       createSparcAsmBackend);
197+
198   TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
199                                       createMCAsmStreamer);
200   TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
201Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
202===================================================================
203--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
204+++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
205@@ -0,0 +1,101 @@
206+//===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===//
207+//
208+//                     The LLVM Compiler Infrastructure
209+//
210+// This file is distributed under the University of Illinois Open Source
211+// License. See LICENSE.TXT for details.
212+//
213+//===----------------------------------------------------------------------===//
214+
215+#include "llvm/MC/MCAsmBackend.h"
216+#include "MCTargetDesc/SparcMCTargetDesc.h"
217+#include "MCTargetDesc/SparcFixupKinds.h"
218+#include "llvm/MC/MCFixupKindInfo.h"
219+#include "llvm/MC/MCObjectWriter.h"
220+#include "llvm/Support/TargetRegistry.h"
221+
222+using namespace llvm;
223+
224+namespace {
225+  class SparcAsmBackend : public MCAsmBackend {
226+
227+  public:
228+    SparcAsmBackend(const Target &T) : MCAsmBackend() {}
229+
230+    unsigned getNumFixupKinds() const {
231+      return Sparc::NumTargetFixupKinds;
232+    }
233+
234+    const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
235+      const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = {
236+        // name                    offset bits  flags
237+        { "fixup_sparc_call30",     0,     30,  MCFixupKindInfo::FKF_IsPCRel },
238+        { "fixup_sparc_br22",       0,     22,  MCFixupKindInfo::FKF_IsPCRel },
239+        { "fixup_sparc_br19",       0,     19,  MCFixupKindInfo::FKF_IsPCRel }
240+      };
241+
242+      if (Kind < FirstTargetFixupKind)
243+        return MCAsmBackend::getFixupKindInfo(Kind);
244+
245+      assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
246+             "Invalid kind!");
247+      return Infos[Kind - FirstTargetFixupKind];
248+    }
249+
250+    bool mayNeedRelaxation(const MCInst &Inst) const {
251+      // FIXME.
252+      return false;
253+    }
254+
255+    /// fixupNeedsRelaxation - Target specific predicate for whether a given
256+    /// fixup requires the associated instruction to be relaxed.
257+    bool fixupNeedsRelaxation(const MCFixup &Fixup,
258+                              uint64_t Value,
259+                              const MCRelaxableFragment *DF,
260+                              const MCAsmLayout &Layout) const {
261+      // FIXME.
262+      assert(0 && "fixupNeedsRelaxation() unimplemented");
263+      return false;
264+    }
265+    void relaxInstruction(const MCInst &Inst, MCInst &Res) const {
266+      // FIXME.
267+      assert(0 && "relaxInstruction() unimplemented");
268+    }
269+
270+    bool writeNopData(uint64_t Count, MCObjectWriter *OW) const {
271+      // FIXME: Zero fill for now.
272+      for (uint64_t i = 0; i != Count; ++i)
273+        OW->Write8(0);
274+      return true;
275+    }
276+  };
277+
278+  class ELFSparcAsmBackend : public SparcAsmBackend {
279+  public:
280+    ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
281+      SparcAsmBackend(T) { }
282+
283+    void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
284+                    uint64_t Value) const {
285+      assert(0 && "applyFixup not implemented yet");
286+    }
287+
288+    MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
289+      assert(0 && "Object Writer not implemented yet");
290+      return 0;
291+    }
292+
293+    virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
294+      return false;
295+    }
296+  };
297+
298+} // end anonymous namespace
299+
300+
301+MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
302+                                          const MCRegisterInfo &MRI,
303+                                          StringRef TT,
304+                                          StringRef CPU) {
305+  return new ELFSparcAsmBackend(T, Triple(TT).getOS());
306+}
307Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
308===================================================================
309--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
310+++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
311@@ -0,0 +1,36 @@
312+//===-- SparcFixupKinds.h - Sparc Specific Fixup Entries --------*- C++ -*-===//
313+//
314+//                     The LLVM Compiler Infrastructure
315+//
316+// This file is distributed under the University of Illinois Open Source
317+// License. See LICENSE.TXT for details.
318+//
319+//===----------------------------------------------------------------------===//
320+
321+#ifndef LLVM_SPARC_FIXUPKINDS_H
322+#define LLVM_SPARC_FIXUPKINDS_H
323+
324+#include "llvm/MC/MCFixup.h"
325+
326+namespace llvm {
327+  namespace Sparc {
328+    enum Fixups {
329+      // fixup_sparc_call30 - 30-bit PC relative relocation for call
330+      fixup_sparc_call30 = FirstTargetFixupKind,
331+
332+      /// fixup_sparc_br22 - 22-bit PC relative relocation for
333+      /// branches
334+      fixup_sparc_br22,
335+
336+      /// fixup_sparc_br22 - 22-bit PC relative relocation for
337+      /// branches on icc/xcc
338+      fixup_sparc_br19,
339+
340+      // Marker
341+      LastTargetFixupKind,
342+      NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
343+    };
344+  }
345+}
346+
347+#endif
348Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
349===================================================================
350--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
351+++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
352@@ -15,11 +15,27 @@
353 #define SPARCMCTARGETDESC_H
354 
355 namespace llvm {
356+class MCAsmBackend;
357+class MCCodeEmitter;
358+class MCContext;
359+class MCInstrInfo;
360+class MCRegisterInfo;
361+class MCSubtargetInfo;
362 class Target;
363+class StringRef;
364 
365 extern Target TheSparcTarget;
366 extern Target TheSparcV9Target;
367 
368+MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII,
369+                                        const MCRegisterInfo &MRI,
370+                                        const MCSubtargetInfo &STI,
371+                                        MCContext &Ctx);
372+MCAsmBackend *createSparcAsmBackend(const Target &T,
373+                                    const MCRegisterInfo &MRI,
374+                                    StringRef TT,
375+                                    StringRef CPU);
376+
377 } // End llvm namespace
378 
379 // Defines symbolic names for Sparc registers.  This defines a mapping from
380Index: lib/Target/Sparc/Makefile
381===================================================================
382--- lib/Target/Sparc/Makefile
383+++ lib/Target/Sparc/Makefile
384@@ -16,7 +16,7 @@ BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenI
385 		SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
386 		SparcGenDAGISel.inc \
387 		SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
388-		SparcGenCodeEmitter.inc
389+		SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc
390 
391 DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
392 
393Index: lib/Target/Sparc/CMakeLists.txt
394===================================================================
395--- lib/Target/Sparc/CMakeLists.txt
396+++ lib/Target/Sparc/CMakeLists.txt
397@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td)
398 tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
399 tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
400 tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
401+tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter)
402 tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
403 tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
404 tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel)
405Index: lib/Target/Sparc/SparcCodeEmitter.cpp
406===================================================================
407--- lib/Target/Sparc/SparcCodeEmitter.cpp
408+++ lib/Target/Sparc/SparcCodeEmitter.cpp
409@@ -72,6 +72,11 @@ class SparcCodeEmitter : public MachineFunctionPas
410   unsigned getMachineOpValue(const MachineInstr &MI,
411                              const MachineOperand &MO) const;
412 
413+  unsigned getCallTargetOpValue(const MachineInstr &MI,
414+                                unsigned) const;
415+  unsigned getBranchTargetOpValue(const MachineInstr &MI,
416+                                  unsigned) const;
417+
418   void emitWord(unsigned Word);
419 
420   unsigned getRelocation(const MachineInstr &MI,
421@@ -181,6 +186,18 @@ unsigned SparcCodeEmitter::getMachineOpValue(const
422     llvm_unreachable("Unable to encode MachineOperand!");
423   return 0;
424 }
425+unsigned SparcCodeEmitter::getCallTargetOpValue(const MachineInstr &MI,
426+                                                unsigned opIdx) const {
427+  const MachineOperand MO = MI.getOperand(opIdx);
428+  return getMachineOpValue(MI, MO);
429+}
430+
431+unsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
432+                                                  unsigned opIdx) const {
433+  const MachineOperand MO = MI.getOperand(opIdx);
434+  return getMachineOpValue(MI, MO);
435+}
436+
437 unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI,
438                                          const MachineOperand &MO) const {
439 
440Index: test/MC/Sparc/sparc-alu-instructions.s
441===================================================================
442--- test/MC/Sparc/sparc-alu-instructions.s
443+++ test/MC/Sparc/sparc-alu-instructions.s
444@@ -0,0 +1,72 @@
445+! RUN: llvm-mc %s -arch=sparc   -show-encoding | FileCheck %s
446+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
447+
448+        ! CHECK: add %g0, %g0, %g0    ! encoding: [0x80,0x00,0x00,0x00]
449+        add %g0, %g0, %g0
450+        ! CHECK: add %g1, %g2, %g3    ! encoding: [0x86,0x00,0x40,0x02]
451+        add %g1, %g2, %g3
452+        ! CHECK: add %o0, %o1, %l0    ! encoding: [0xa0,0x02,0x00,0x09]
453+        add %r8, %r9, %l0
454+        ! CHECK: add %o0, 10,  %l0    ! encoding: [0xa0,0x02,0x20,0x0a]
455+        add %o0, 10, %l0
456+
457+        ! CHECK: addcc %g1, %g2, %g3  ! encoding: [0x86,0x80,0x40,0x02]
458+        addcc %g1, %g2, %g3
459+
460+        ! CHECK: addxcc %g1, %g2, %g3 ! encoding: [0x86,0xc0,0x40,0x02]
461+        addxcc %g1, %g2, %g3
462+
463+        ! CHECK: udiv %g1, %g2, %g3   ! encoding: [0x86,0x70,0x40,0x02]
464+        udiv %g1, %g2, %g3
465+
466+        ! CHECK: sdiv %g1, %g2, %g3   ! encoding: [0x86,0x78,0x40,0x02]
467+        sdiv %g1, %g2, %g3
468+
469+        ! CHECK: and %g1, %g2, %g3    ! encoding: [0x86,0x08,0x40,0x02]
470+        and %g1, %g2, %g3
471+        ! CHECK: andn %g1, %g2, %g3   ! encoding: [0x86,0x28,0x40,0x02]
472+        andn %g1, %g2, %g3
473+        ! CHECK: or %g1, %g2, %g3     ! encoding: [0x86,0x10,0x40,0x02]
474+        or  %g1, %g2, %g3
475+        ! CHECK: orn %g1, %g2, %g3    ! encoding: [0x86,0x30,0x40,0x02]
476+        orn %g1, %g2, %g3
477+        ! CHECK: xor %g1, %g2, %g3    ! encoding: [0x86,0x18,0x40,0x02]
478+        xor %g1, %g2, %g3
479+        ! CHECK: xnor %g1, %g2, %g3   ! encoding: [0x86,0x38,0x40,0x02]
480+        xnor %g1, %g2, %g3
481+
482+        ! CHECK: umul %g1, %g2, %g3   ! encoding: [0x86,0x50,0x40,0x02]
483+        umul %g1, %g2, %g3
484+
485+        ! CHECK: smul %g1, %g2, %g3   ! encoding: [0x86,0x58,0x40,0x02]
486+        smul %g1, %g2, %g3
487+
488+        ! CHECK: nop                  ! encoding: [0x01,0x00,0x00,0x00]
489+        nop
490+
491+        ! CHECK: sethi 10, %l0        ! encoding: [0x21,0x00,0x00,0x0a]
492+        sethi 10, %l0
493+
494+        ! CHECK: sll %g1, %g2, %g3    ! encoding: [0x87,0x28,0x40,0x02]
495+        sll %g1, %g2, %g3
496+        ! CHECK: sll %g1, 31, %g3     ! encoding: [0x87,0x28,0x60,0x1f]
497+        sll %g1, 31, %g3
498+
499+        ! CHECK: srl %g1, %g2, %g3    ! encoding: [0x87,0x30,0x40,0x02]
500+        srl %g1, %g2, %g3
501+        ! CHECK: srl %g1, 31, %g3     ! encoding: [0x87,0x30,0x60,0x1f]
502+        srl %g1, 31, %g3
503+
504+        ! CHECK: sra %g1, %g2, %g3    ! encoding: [0x87,0x38,0x40,0x02]
505+        sra %g1, %g2, %g3
506+        ! CHECK: sra %g1, 31, %g3     ! encoding: [0x87,0x38,0x60,0x1f]
507+        sra %g1, 31, %g3
508+
509+        ! CHECK: sub %g1, %g2, %g3    ! encoding: [0x86,0x20,0x40,0x02]
510+        sub %g1, %g2, %g3
511+        ! CHECK: subcc %g1, %g2, %g3  ! encoding: [0x86,0xa0,0x40,0x02]
512+        subcc %g1, %g2, %g3
513+
514+        ! CHECK: subxcc %g1, %g2, %g3 ! encoding: [0x86,0xe0,0x40,0x02]
515+        subxcc %g1, %g2, %g3
516+
517