]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r198533-sparc.diff
1 Pull in r198533 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3   [Sparc] Add initial implementation of MC Code emitter for sparc.
4
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7 Index: lib/Target/Sparc/SparcInstrInfo.td
8 ===================================================================
9 --- lib/Target/Sparc/SparcInstrInfo.td
10 +++ lib/Target/Sparc/SparcInstrInfo.td
11 @@ -100,9 +100,14 @@ def MEMri : Operand<iPTR> {
12  def TLSSym : Operand<iPTR>;
13  
14  // Branch targets have OtherVT type.
15 -def brtarget : Operand<OtherVT>;
16 -def calltarget : Operand<i32>;
17 +def brtarget : Operand<OtherVT> {
18 +  let EncoderMethod = "getBranchTargetOpValue";
19 +}
20  
21 +def calltarget : Operand<i32> {
22 +  let EncoderMethod = "getCallTargetOpValue";
23 +}
24 +
25  // Operand for printing out a condition code.
26  let PrintMethod = "printCCOperand" in
27    def CCOp : Operand<i32>;
28 Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
29 ===================================================================
30 --- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
31 +++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
32 @@ -1,6 +1,8 @@
33  add_llvm_library(LLVMSparcDesc
34 +  SparcAsmBackend.cpp
35 +  SparcMCAsmInfo.cpp
36 +  SparcMCCodeEmitter.cpp
37    SparcMCTargetDesc.cpp
38 -  SparcMCAsmInfo.cpp
39    SparcMCExpr.cpp
40    SparcTargetStreamer.cpp
41    )
42 Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
43 ===================================================================
44 --- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
45 +++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
46 @@ -0,0 +1,131 @@
47 +//===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===//
48 +//
49 +//                     The LLVM Compiler Infrastructure
50 +//
51 +// This file is distributed under the University of Illinois Open Source
52 +// License. See LICENSE.TXT for details.
53 +//
54 +//===----------------------------------------------------------------------===//
55 +//
56 +// This file implements the SparcMCCodeEmitter class.
57 +//
58 +//===----------------------------------------------------------------------===//
59 +
60 +#define DEBUG_TYPE "mccodeemitter"
61 +#include "SparcMCTargetDesc.h"
62 +#include "MCTargetDesc/SparcFixupKinds.h"
63 +#include "llvm/MC/MCCodeEmitter.h"
64 +#include "llvm/MC/MCContext.h"
65 +#include "llvm/MC/MCExpr.h"
66 +#include "llvm/MC/MCInst.h"
67 +#include "llvm/MC/MCRegisterInfo.h"
68 +#include "llvm/ADT/Statistic.h"
69 +#include "llvm/Support/raw_ostream.h"
70 +
71 +using namespace llvm;
72 +
73 +STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
74 +
75 +namespace {
76 +class SparcMCCodeEmitter : public MCCodeEmitter {
77 +  SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
78 +  void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
79 +  MCContext &Ctx;
80 +
81 +public:
82 +  SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {}
83 +
84 +  ~SparcMCCodeEmitter() {}
85 +
86 +  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
87 +                         SmallVectorImpl<MCFixup> &Fixups) const;
88 +
89 +  // getBinaryCodeForInstr - TableGen'erated function for getting the
90 +  // binary encoding for an instruction.
91 +  uint64_t getBinaryCodeForInstr(const MCInst &MI,
92 +                                 SmallVectorImpl<MCFixup> &Fixups) const;
93 +
94 +  /// getMachineOpValue - Return binary encoding of operand. If the machine
95 +  /// operand requires relocation, record the relocation and return zero.
96 +  unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
97 +                             SmallVectorImpl<MCFixup> &Fixups) const;
98 +
99 +  unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
100 +                             SmallVectorImpl<MCFixup> &Fixups) const;
101 +  unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
102 +                             SmallVectorImpl<MCFixup> &Fixups) const;
103 +
104 +};
105 +} // end anonymous namespace
106 +
107 +MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
108 +                                              const MCRegisterInfo &MRI,
109 +                                              const MCSubtargetInfo &STI,
110 +                                              MCContext &Ctx) {
111 +  return new SparcMCCodeEmitter(Ctx);
112 +}
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"
178 Index: 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,
201 Index: 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 +}
307 Index: 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
348 Index: 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
380 Index: 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  
393 Index: 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)
405 Index: 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  
440 Index: 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 +