2011-09-01 19:27:58 -05:00
|
|
|
import std::{vec, str};
|
|
|
|
import std::str::sbuf;
|
2011-08-24 07:54:55 -05:00
|
|
|
import lib::llvm::llvm;
|
2011-09-02 17:34:58 -05:00
|
|
|
import llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, Opcode,
|
|
|
|
ModuleRef};
|
2011-09-21 05:40:27 -05:00
|
|
|
import trans_common::{block_ctxt, T_ptr, T_nil, T_int, T_i8, T_i1, val_ty};
|
2011-08-24 07:54:55 -05:00
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn B(cx: @block_ctxt) -> BuilderRef {
|
2011-08-30 07:02:20 -05:00
|
|
|
let b = *cx.fcx.lcx.ccx.builder;
|
|
|
|
llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
|
|
|
|
ret b;
|
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
// The difference between a block being unreachable and being terminated is
|
|
|
|
// somewhat obscure, and has to do with error checking. When a block is
|
|
|
|
// terminated, we're saying that trying to add any further statements in the
|
|
|
|
// block is an error. On the other hand, if something is unreachable, that
|
|
|
|
// means that the block was terminated in some way that we don't want to check
|
|
|
|
// for (fail/break/ret statements, call to diverging functions, etc), and
|
|
|
|
// further instructions to the block should simply be ignored.
|
|
|
|
|
|
|
|
fn RetVoid(cx: @block_ctxt) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-09-02 17:34:58 -05:00
|
|
|
assert (!cx.terminated);
|
2011-08-24 07:54:55 -05:00
|
|
|
cx.terminated = true;
|
2011-09-21 05:40:27 -05:00
|
|
|
llvm::LLVMBuildRetVoid(B(cx));
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn Ret(cx: @block_ctxt, V: ValueRef) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-09-02 17:34:58 -05:00
|
|
|
assert (!cx.terminated);
|
2011-08-24 07:54:55 -05:00
|
|
|
cx.terminated = true;
|
2011-09-21 05:40:27 -05:00
|
|
|
llvm::LLVMBuildRet(B(cx), V);
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-09-02 17:34:58 -05:00
|
|
|
assert (!cx.terminated);
|
2011-08-24 07:54:55 -05:00
|
|
|
cx.terminated = true;
|
2011-09-21 05:40:27 -05:00
|
|
|
llvm::LLVMBuildAggregateRet(B(cx), vec::to_ptr(RetVals),
|
|
|
|
vec::len(RetVals));
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn Br(cx: @block_ctxt, Dest: BasicBlockRef) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-09-02 17:34:58 -05:00
|
|
|
assert (!cx.terminated);
|
2011-08-24 07:54:55 -05:00
|
|
|
cx.terminated = true;
|
2011-09-21 05:40:27 -05:00
|
|
|
llvm::LLVMBuildBr(B(cx), Dest);
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef,
|
2011-09-21 05:40:27 -05:00
|
|
|
Else: BasicBlockRef) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-09-02 17:34:58 -05:00
|
|
|
assert (!cx.terminated);
|
2011-08-24 07:54:55 -05:00
|
|
|
cx.terminated = true;
|
2011-09-21 05:40:27 -05:00
|
|
|
llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Switch(cx: @block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
|
2011-09-21 05:40:27 -05:00
|
|
|
-> ValueRef {
|
|
|
|
if cx.unreachable { ret _Undef(V); }
|
|
|
|
assert !cx.terminated;
|
2011-08-24 07:54:55 -05:00
|
|
|
cx.terminated = true;
|
2011-08-30 07:02:20 -05:00
|
|
|
ret llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases);
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn AddCase(S: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef) {
|
|
|
|
if llvm::LLVMIsUndef(S) == lib::llvm::True { ret; }
|
|
|
|
llvm::LLVMAddCase(S, OnVal, Dest);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn IndirectBr(cx: @block_ctxt, Addr: ValueRef, NumDests: uint) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-09-02 17:34:58 -05:00
|
|
|
assert (!cx.terminated);
|
2011-08-24 07:54:55 -05:00
|
|
|
cx.terminated = true;
|
2011-09-21 05:40:27 -05:00
|
|
|
llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests);
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Invoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
2011-09-21 05:40:27 -05:00
|
|
|
Then: BasicBlockRef, Catch: BasicBlockRef) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-09-02 17:34:58 -05:00
|
|
|
assert (!cx.terminated);
|
2011-08-24 07:54:55 -05:00
|
|
|
cx.terminated = true;
|
2011-09-21 05:40:27 -05:00
|
|
|
str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args),
|
|
|
|
vec::len(Args), Then, Catch, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 11:36:51 -05:00
|
|
|
fn FastInvoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
2011-09-21 05:40:27 -05:00
|
|
|
Then: BasicBlockRef, Catch: BasicBlockRef) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-09-07 13:46:53 -05:00
|
|
|
assert (!cx.terminated);
|
|
|
|
cx.terminated = true;
|
2011-09-21 05:40:27 -05:00
|
|
|
let v = str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args),
|
|
|
|
vec::len(Args), Then, Catch, buf)
|
|
|
|
});
|
2011-09-07 13:46:53 -05:00
|
|
|
llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv);
|
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn Unreachable(cx: @block_ctxt) {
|
|
|
|
if cx.unreachable { ret; }
|
|
|
|
cx.unreachable = true;
|
|
|
|
if !cx.terminated { llvm::LLVMBuildUnreachable(B(cx)); }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn _Undef(val: ValueRef) -> ValueRef {
|
|
|
|
ret llvm::LLVMGetUndef(val_ty(val));
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Arithmetic */
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Add(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildAdd(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn NSWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn NUWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildFAdd(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Sub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildSub(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn NSWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn NUWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildFSub(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Mul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildMul(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn NSWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn NUWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildFMul(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn UDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildUDiv(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn SDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildSDiv(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn ExactSDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildFDiv(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn URem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildURem(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn SRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildSRem(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildFRem(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Shl(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildShl(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn LShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildLShr(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn AShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildAShr(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn And(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildAnd(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Or(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildOr(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Xor(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildXor(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn BinOp(cx: @block_ctxt, Op: Opcode, LHS: ValueRef, RHS: ValueRef) ->
|
2011-09-02 17:34:58 -05:00
|
|
|
ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(LHS); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Neg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(V); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNeg(B(cx), V, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn NSWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(V); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNSWNeg(B(cx), V, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn NUWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(V); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNUWNeg(B(cx), V, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(V); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildFNeg(B(cx), V, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
2011-08-26 17:36:18 -05:00
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Not(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(V); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildNot(B(cx), V, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Memory */
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Malloc(cx: @block_ctxt, Ty: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildMalloc(B(cx), Ty, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn ArrayMalloc(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Alloca(cx: @block_ctxt, Ty: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildAlloca(B(cx), Ty, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn ArrayAlloca(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn Free(cx: @block_ctxt, PointerVal: ValueRef) {
|
|
|
|
if cx.unreachable { ret; }
|
|
|
|
llvm::LLVMBuildFree(B(cx), PointerVal);
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable {
|
|
|
|
let ty = val_ty(PointerVal);
|
|
|
|
let eltty = if llvm::LLVMGetTypeKind(ty) == 11 {
|
|
|
|
llvm::LLVMGetElementType(ty) } else { T_int() };
|
|
|
|
ret llvm::LLVMGetUndef(eltty);
|
|
|
|
}
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildLoad(B(cx), PointerVal, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn Store(cx: @block_ctxt, Val: ValueRef, Ptr: ValueRef) {
|
|
|
|
if cx.unreachable { ret; }
|
|
|
|
llvm::LLVMBuildStore(B(cx), Val, Ptr);
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn GEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
|
|
|
ret str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildGEP(B(cx), Pointer,
|
|
|
|
vec::to_ptr(Indices),
|
|
|
|
vec::len(Indices), buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn InBoundsGEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) ->
|
2011-09-02 17:34:58 -05:00
|
|
|
ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
|
|
|
ret str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, vec::to_ptr(Indices),
|
|
|
|
vec::len(Indices), buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn StructGEP(cx: @block_ctxt, Pointer: ValueRef, Idx: uint) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn GlobalString(cx: @block_ctxt, _Str: sbuf) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildGlobalString(B(cx), _Str, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn GlobalStringPtr(cx: @block_ctxt, _Str: sbuf) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Casts */
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Trunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildTrunc(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn ZExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildZExt(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn SExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildSExt(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FPToUI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FPToSI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn UIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn SIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FPTrunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FPExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildFPExt(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn PtrToInt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn IntToPtr(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn BitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildBitCast(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn ZExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
2011-09-02 17:34:58 -05:00
|
|
|
ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn SExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
2011-09-02 17:34:58 -05:00
|
|
|
ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn TruncOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
2011-09-02 17:34:58 -05:00
|
|
|
ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Cast(cx: @block_ctxt, Op: Opcode, Val: ValueRef, DestTy: TypeRef,
|
2011-09-02 17:34:58 -05:00
|
|
|
_Name: sbuf) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn PointerCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn IntCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildIntCast(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FPCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildFPCast(B(cx), Val, DestTy, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Comparisons */
|
2011-09-12 04:27:30 -05:00
|
|
|
fn ICmp(cx: @block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FCmp(cx: @block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Miscellaneous instructions */
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Phi(cx: @block_ctxt, Ty: TypeRef, vals: [ValueRef], bbs: [BasicBlockRef])
|
|
|
|
-> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
2011-09-02 17:34:58 -05:00
|
|
|
let phi = str::as_buf("", {|buf| llvm::LLVMBuildPhi(B(cx), Ty, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
assert (vec::len::<ValueRef>(vals) == vec::len::<BasicBlockRef>(bbs));
|
|
|
|
llvm::LLVMAddIncoming(phi, vec::to_ptr(vals), vec::to_ptr(bbs),
|
|
|
|
vec::len(vals));
|
|
|
|
ret phi;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn AddIncomingToPhi(phi: ValueRef, vals: [ValueRef], bbs: [BasicBlockRef]) {
|
2011-09-21 05:40:27 -05:00
|
|
|
if llvm::LLVMIsUndef(phi) == lib::llvm::True { ret; }
|
2011-08-24 07:54:55 -05:00
|
|
|
assert (vec::len::<ValueRef>(vals) == vec::len::<BasicBlockRef>(bbs));
|
|
|
|
llvm::LLVMAddIncoming(phi, vec::to_ptr(vals), vec::to_ptr(bbs),
|
|
|
|
vec::len(vals));
|
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn _UndefReturn(Fn: ValueRef) -> ValueRef {
|
|
|
|
let ty = val_ty(Fn);
|
|
|
|
let retty = if llvm::LLVMGetTypeKind(ty) == 8 {
|
|
|
|
llvm::LLVMGetReturnType(ty) } else { T_int() };
|
|
|
|
ret llvm::LLVMGetUndef(retty);
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _UndefReturn(Fn); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
|
|
|
vec::len(Args), buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _UndefReturn(Fn); }
|
2011-09-02 17:34:58 -05:00
|
|
|
let v =
|
|
|
|
str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
|
|
|
vec::len(Args), buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv);
|
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint)
|
2011-09-02 17:34:58 -05:00
|
|
|
-> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _UndefReturn(Fn); }
|
2011-09-02 17:34:58 -05:00
|
|
|
let v =
|
|
|
|
str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
|
|
|
vec::len(Args), buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
llvm::LLVMSetInstructionCallConv(v, Conv);
|
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn Select(cx: @block_ctxt, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
|
2011-09-02 17:34:58 -05:00
|
|
|
ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret _Undef(Then); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildSelect(B(cx), If, Then, Else, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn VAArg(cx: @block_ctxt, list: ValueRef, Ty: TypeRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildVAArg(B(cx), list, Ty, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn ExtractElement(cx: @block_ctxt, VecVal: ValueRef, Index: ValueRef) ->
|
2011-09-02 17:34:58 -05:00
|
|
|
ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildExtractElement(B(cx), VecVal, Index,
|
|
|
|
buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn InsertElement(cx: @block_ctxt, VecVal: ValueRef, EltVal: ValueRef,
|
2011-09-21 05:40:27 -05:00
|
|
|
Index: ValueRef) {
|
|
|
|
if cx.unreachable { ret; }
|
|
|
|
str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn ShuffleVector(cx: @block_ctxt, V1: ValueRef, V2: ValueRef,
|
|
|
|
Mask: ValueRef) {
|
|
|
|
if cx.unreachable { ret; }
|
|
|
|
str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn ExtractValue(cx: @block_ctxt, AggVal: ValueRef, Index: uint) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf|
|
|
|
|
llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn InsertValue(cx: @block_ctxt, AggVal: ValueRef, EltVal: ValueRef,
|
2011-09-21 05:40:27 -05:00
|
|
|
Index: uint) {
|
|
|
|
if cx.unreachable { ret; }
|
|
|
|
str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index, buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn IsNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildIsNull(B(cx), Val, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn IsNotNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("", {|buf| llvm::LLVMBuildIsNotNull(B(cx), Val, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn PtrDiff(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_int()); }
|
2011-09-02 17:34:58 -05:00
|
|
|
ret str::as_buf("",
|
|
|
|
{|buf| llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-21 05:40:27 -05:00
|
|
|
fn Trap(cx: @block_ctxt) {
|
|
|
|
if cx.unreachable { ret; }
|
2011-08-30 07:02:20 -05:00
|
|
|
let b = B(cx);
|
|
|
|
let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
|
2011-08-24 07:54:55 -05:00
|
|
|
let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
|
|
|
|
let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
|
2011-09-02 17:34:58 -05:00
|
|
|
let T: ValueRef =
|
|
|
|
str::as_buf("llvm.trap", {|buf| llvm::LLVMGetNamedFunction(M, buf) });
|
2011-08-24 07:54:55 -05:00
|
|
|
assert (T as int != 0);
|
|
|
|
let Args: [ValueRef] = [];
|
2011-09-21 05:40:27 -05:00
|
|
|
str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), vec::len(Args), buf)
|
|
|
|
});
|
2011-08-24 07:54:55 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 11:36:51 -05:00
|
|
|
fn LandingPad(cx: @block_ctxt, Ty: TypeRef, PersFn: ValueRef,
|
2011-09-07 13:58:49 -05:00
|
|
|
NumClauses: uint) -> ValueRef {
|
2011-09-21 05:40:27 -05:00
|
|
|
assert !cx.terminated && !cx.unreachable;
|
|
|
|
ret str::as_buf("", {|buf|
|
|
|
|
llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, NumClauses, buf)
|
|
|
|
});
|
2011-09-07 13:58:49 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 11:36:51 -05:00
|
|
|
fn SetCleanup(_cx: @block_ctxt, LandingPad: ValueRef) {
|
2011-09-07 13:58:49 -05:00
|
|
|
llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
|
|
|
|
}
|
|
|
|
|
2011-09-12 11:36:51 -05:00
|
|
|
fn Resume(cx: @block_ctxt, Exn: ValueRef) -> ValueRef {
|
2011-09-07 16:28:02 -05:00
|
|
|
assert (!cx.terminated);
|
|
|
|
cx.terminated = true;
|
|
|
|
ret llvm::LLVMBuildResume(B(cx), Exn);
|
|
|
|
}
|
|
|
|
|
2011-08-24 07:54:55 -05:00
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
|
|
// End:
|
|
|
|
//
|