1239310Sdim//===-- NVPTXutil.cpp - Functions exported to CodeGen --*- C++ -*-===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim//
10239310Sdim// This file contains the functions that can be used in CodeGen.
11239310Sdim//
12239310Sdim//===----------------------------------------------------------------------===//
13239310Sdim
14239310Sdim#include "NVPTXutil.h"
15239310Sdim#include "NVPTX.h"
16239310Sdim
17239310Sdimusing namespace llvm;
18239310Sdim
19239310Sdimnamespace llvm {
20239310Sdim
21249423Sdimbool isParamLoad(const MachineInstr *MI) {
22239310Sdim  if ((MI->getOpcode() != NVPTX::LD_i32_avar) &&
23239310Sdim      (MI->getOpcode() != NVPTX::LD_i64_avar))
24239310Sdim    return false;
25239310Sdim  if (MI->getOperand(2).isImm() == false)
26239310Sdim    return false;
27239310Sdim  if (MI->getOperand(2).getImm() != NVPTX::PTXLdStInstCode::PARAM)
28239310Sdim    return false;
29239310Sdim  return true;
30239310Sdim}
31239310Sdim
32249423Sdim#define DATA_MASK 0x7f
33249423Sdim#define DIGIT_WIDTH 7
34249423Sdim#define MORE_BYTES 0x80
35239310Sdim
36249423Sdimstatic int encode_leb128(uint64_t val, int *nbytes, char *space, int splen) {
37239310Sdim  char *a;
38239310Sdim  char *end = space + splen;
39239310Sdim
40239310Sdim  a = space;
41239310Sdim  do {
42239310Sdim    unsigned char uc;
43239310Sdim
44239310Sdim    if (a >= end)
45239310Sdim      return 1;
46239310Sdim    uc = val & DATA_MASK;
47239310Sdim    val >>= DIGIT_WIDTH;
48239310Sdim    if (val != 0)
49239310Sdim      uc |= MORE_BYTES;
50239310Sdim    *a = uc;
51239310Sdim    a++;
52239310Sdim  } while (val);
53239310Sdim  *nbytes = a - space;
54239310Sdim  return 0;
55239310Sdim}
56239310Sdim
57239310Sdim#undef DATA_MASK
58239310Sdim#undef DIGIT_WIDTH
59239310Sdim#undef MORE_BYTES
60239310Sdim
61249423Sdimuint64_t encode_leb128(const char *str) {
62249423Sdim  union {
63249423Sdim    uint64_t x;
64249423Sdim    char a[8];
65249423Sdim  } temp64;
66239310Sdim
67239310Sdim  temp64.x = 0;
68239310Sdim
69249423Sdim  for (unsigned i = 0, e = strlen(str); i != e; ++i)
70249423Sdim    temp64.a[i] = str[e - 1 - i];
71239310Sdim
72239310Sdim  char encoded[16];
73239310Sdim  int nbytes;
74239310Sdim
75239310Sdim  int retval = encode_leb128(temp64.x, &nbytes, encoded, 16);
76239310Sdim
77249423Sdim  (void) retval;
78249423Sdim  assert(retval == 0 && "Encoding to leb128 failed");
79239310Sdim
80239310Sdim  assert(nbytes <= 8 &&
81239310Sdim         "Cannot support register names with leb128 encoding > 8 bytes");
82239310Sdim
83239310Sdim  temp64.x = 0;
84249423Sdim  for (int i = 0; i < nbytes; ++i)
85239310Sdim    temp64.a[i] = encoded[i];
86239310Sdim
87239310Sdim  return temp64.x;
88239310Sdim}
89239310Sdim
90239310Sdim} // end namespace llvm
91