public
Description: LLVM bindings for Ruby
Homepage: http://llvmruby.org
Clone URL: git://github.com/tombagby/llvmruby.git
tombagby (author)
Sun Oct 19 13:32:34 -0700 2008
commit  f26df3f0f9db776e33e04ee129d1a754b72e3bb1
tree    b672d413cec8498058334960fa8708242b2baa1e
parent  da0d2abff09f6f722bddc4dd9ba43045174e275c
llvmruby / ext / llvm_instruction.cpp
100644 183 lines (150 sloc) 4.596 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include "llvmruby.h"
#include <sstream>
 
extern VALUE cLLVMInstruction;
extern VALUE cLLVMBinaryOps;
 
extern "C" {
 
VALUE
llvm_instruction_wrap(Instruction* i) {
   return Data_Wrap_Struct(cLLVMInstruction, NULL, NULL, i);
}
 
VALUE
llvm_instruction_inspect(VALUE self) {
  Instruction *i = LLVM_INSTRUCTION(self);
  std::ostringstream strstrm;
  strstrm << *i;
  return rb_str_new2(strstrm.str().c_str());
}
 
VALUE
llvm_instruction_get_opcode_name(VALUE self) {
  Instruction *i = LLVM_INSTRUCTION(self);
  std::string name = i->getOpcodeName();
  return rb_str_new2(name.c_str());
}
 
#define DATA_GET_TERMINATOR_INST TerminatorInst *ti; Data_Get_Struct(self, TerminatorInst, ti);
 
VALUE
llvm_terminator_inst_num_successors(VALUE self) {
  DATA_GET_TERMINATOR_INST
  return INT2FIX(ti->getNumSuccessors());
}
 
VALUE
llvm_terminator_inst_get_successor(VALUE self, VALUE ridx) {
  DATA_GET_TERMINATOR_INST
  BasicBlock *bb = ti->getSuccessor(FIX2INT(ridx));
  return llvm_basic_block_wrap(bb);
}
 
VALUE
llvm_terminator_inst_set_successor(VALUE self, VALUE ridx, VALUE rbb) {
  DATA_GET_TERMINATOR_INST
 
  BasicBlock *bb;
  Data_Get_Struct(rbb, BasicBlock, bb);
 
  ti->setSuccessor(FIX2INT(ridx), bb);
  return rbb;
}
 
#define DATA_GET_BRANCH_INST BranchInst *bi; Data_Get_Struct(self, BranchInst, bi);
 
VALUE
llvm_branch_inst_is_unconditional(VALUE self) {
  DATA_GET_BRANCH_INST
  return bi->isUnconditional() ? Qtrue : Qfalse;
}
 
VALUE
llvm_branch_inst_is_conditional(VALUE self) {
  DATA_GET_BRANCH_INST
  return bi->isConditional() ? Qtrue : Qfalse;
}
 
VALUE
llvm_branch_inst_get_condition(VALUE self) {
  DATA_GET_BRANCH_INST
  return llvm_value_wrap(bi->getCondition());
}
 
VALUE
llvm_branch_inst_set_condition(VALUE self, VALUE rv) {
  DATA_GET_BRANCH_INST
  
  Value *v;
  Data_Get_Struct(rv, Value, v);
 
  bi->setCondition(v);
  return rv;
}
 
#define DATA_GET_SWITCH_INST SwitchInst *si; Data_Get_Struct(self, SwitchInst, si);
 
VALUE
llvm_switch_inst_get_default_dest(VALUE self) {
  DATA_GET_SWITCH_INST
  BasicBlock *bb = si->getDefaultDest();
  return llvm_basic_block_wrap(bb);
}
 
VALUE
llvm_switch_inst_get_num_cases(VALUE self) {
  DATA_GET_SWITCH_INST
  return INT2FIX(si->getNumCases());
}
 
VALUE
llvm_switch_inst_add_case(VALUE self, VALUE rci, VALUE rbb) {
  DATA_GET_SWITCH_INST
  
  ConstantInt *ci;
  Data_Get_Struct(rci, ConstantInt, ci);
 
  BasicBlock *bb;
  Data_Get_Struct(rbb, BasicBlock, bb);
 
  si->addCase(ci, bb);
  return self;
}
 
 
#define DEFINE_INST(type, name) rb_define_const(cLLVMInstruction, #name, INT2FIX(Instruction::name));
#define DEFINE_BINARY_INST(name) DEFINE_INST(cLLVMBinaryOps, name)
#define DEFINE_PRED(name) rb_define_const(cLLVMInstruction, #name, INT2FIX(ICmpInst::name));
#define DEFINE_FPRED(name) rb_define_const(cLLVMInstruction, #name, INT2FIX(FCmpInst::name));
#define DEFINE_CAST(name) rb_define_const(cLLVMInstruction, #name, INT2FIX(Instruction::name));
 
void init_instructions() {
  // Standard binary operators
  DEFINE_BINARY_INST(Add)
  DEFINE_BINARY_INST(Sub)
  DEFINE_BINARY_INST(Mul)
  DEFINE_BINARY_INST(UDiv)
  DEFINE_BINARY_INST(SDiv)
  DEFINE_BINARY_INST(FDiv)
  DEFINE_BINARY_INST(URem)
  DEFINE_BINARY_INST(SRem)
  DEFINE_BINARY_INST(FRem)
 
  // Logical operators (integer operands)
  DEFINE_BINARY_INST(Shl) // Shift left (logical)
  DEFINE_BINARY_INST(LShr) // Shift right (logical)
  DEFINE_BINARY_INST(AShr) // shift right (arithmetic)
  DEFINE_BINARY_INST(And)
  DEFINE_BINARY_INST(Or)
  DEFINE_BINARY_INST(Xor)
 
  // Integer predicates
  DEFINE_PRED(ICMP_EQ) // equal
  DEFINE_PRED(ICMP_NE) // not equal
  DEFINE_PRED(ICMP_UGT) // unsigned greater than
  DEFINE_PRED(ICMP_UGE) // unsigned greater or equal
  DEFINE_PRED(ICMP_ULT) // unsigned less than
  DEFINE_PRED(ICMP_ULE) // unsigned less or equal
  DEFINE_PRED(ICMP_SGT) // signed greater than
  DEFINE_PRED(ICMP_SGE) // signed greater or equal
  DEFINE_PRED(ICMP_SLT) // signed less than
  DEFINE_PRED(ICMP_SLE) // signed less or equal
 
  DEFINE_FPRED(FCMP_OEQ)
  DEFINE_FPRED(FCMP_OGT)
  DEFINE_FPRED(FCMP_OGE)
  DEFINE_FPRED(FCMP_OLT)
  DEFINE_FPRED(FCMP_OLE)
  DEFINE_FPRED(FCMP_ONE)
  DEFINE_FPRED(FCMP_ORD)
  DEFINE_FPRED(FCMP_UNO)
  DEFINE_FPRED(FCMP_UEQ)
  DEFINE_FPRED(FCMP_UGT)
  DEFINE_FPRED(FCMP_UGE)
  DEFINE_FPRED(FCMP_ULT)
  DEFINE_FPRED(FCMP_ULE)
  DEFINE_FPRED(FCMP_UNE)
 
  DEFINE_CAST(Trunc)
  DEFINE_CAST(ZExt)
  DEFINE_CAST(SExt)
  DEFINE_CAST(FPToUI)
  DEFINE_CAST(FPToSI)
  DEFINE_CAST(UIToFP)
  DEFINE_CAST(SIToFP)
  DEFINE_CAST(FPTrunc)
  DEFINE_CAST(FPExt)
  DEFINE_CAST(PtrToInt)
  DEFINE_CAST(IntToPtr)
  DEFINE_CAST(BitCast)
}
}