void JitFragmentWriter::emitPrint(RewriterVar* dest, RewriterVar* var, bool nl) { if (!dest) dest = call(false, (void*)getSysStdout); if (!var) var = imm(0ul); call(false, (void*)printHelper, dest, var, imm(nl)); }
void GGLAssembler::build_fog( component_t& temp, // incomming fragment / output int component, Scratch& regs) { if (mInfo[component].fog) { Scratch scratches(registerFile()); comment("fog"); integer_t fragment(temp.reg, temp.h, temp.flags); if (!(temp.flags & CORRUPTIBLE)) { temp.reg = regs.obtain(); temp.flags |= CORRUPTIBLE; } integer_t fogColor(scratches.obtain(), 8, CORRUPTIBLE); LDRB(AL, fogColor.reg, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(state.fog.color[component]))); integer_t factor(scratches.obtain(), 16, CORRUPTIBLE); CONTEXT_LOAD(factor.reg, generated_vars.f); // clamp fog factor (TODO: see if there is a way to guarantee // we won't overflow, when setting the iterators) BIC(AL, 0, factor.reg, factor.reg, reg_imm(factor.reg, ASR, 31)); CMP(AL, factor.reg, imm( 0x10000 )); MOV(HS, 0, factor.reg, imm( 0x10000 )); build_blendFOneMinusF(temp, factor, fragment, fogColor); } }
void JitFragmentWriter::emitExec(RewriterVar* code, RewriterVar* globals, RewriterVar* locals, FutureFlags flags) { if (!globals) globals = imm(0ul); if (!locals) locals = imm(0ul); call(false, (void*)exec, code, globals, locals, imm(flags)); }
void JitFragmentWriter::emitDelName(InternedString name) { call(false, (void*)ASTInterpreterJitInterface::delNameHelper, getInterp(), #ifndef NDEBUG imm(asUInt(name).first), imm(asUInt(name).second)); #else imm(asUInt(name))); #endif }
RewriterVar* JitFragmentWriter::emitDeref(InternedString s) { return call(false, (void*)ASTInterpreterJitInterface::derefHelper, getInterp(), #ifndef NDEBUG imm(asUInt(s).first), imm(asUInt(s).second)); #else imm(asUInt(s))); #endif }
static void addi(struct DisasmPara_PPC *dp,ppc_word in,char *ext) { if ((in&0x08000000) && !PPCGETA(in)) { sprintf(dp->opcode,"l%s",ext); /* li, lis */ imm(dp,in,0,3); } else { sprintf(dp->opcode,"%s%s",(in&0x8000)?"sub":"add",ext); if (in & 0x8000) in = (in^0xffff) + 1; imm(dp,in,1,0); } }
RewriterVar* JitFragmentWriter::emitCreateTuple(const llvm::ArrayRef<RewriterVar*> values) { auto num = values.size(); if (num == 0) return imm(EmptyTuple); else if (num == 1) return call(false, (void*)BoxedTuple::create1, values[0]); else if (num == 2) return call(false, (void*)BoxedTuple::create2, values[0], values[1]); else if (num == 3) return call(false, (void*)BoxedTuple::create3, values[0], values[1], values[2]); else return call(false, (void*)createTupleHelper, imm(num), allocArgs(values)); }
void GGLAssembler::component_sat(const component_t& v) { const int one = ((1<<v.size())-1)<<v.l; CMP(AL, v.reg, imm( 1<<v.h )); if (isValidImmediate(one)) { MOV(HS, 0, v.reg, imm( one )); } else if (isValidImmediate(~one)) { MVN(HS, 0, v.reg, imm( ~one )); } else { MOV(HS, 0, v.reg, imm( 1<<v.h )); SUB(HS, 0, v.reg, v.reg, imm( 1<<v.l )); } }
void GGLAssembler::extract(integer_t& d, int s, int h, int l, int bits) { const int maskLen = h-l; #ifdef __mips__ assert(maskLen<=11); #else assert(maskLen<=8); #endif assert(h); #if __ARM_ARCH__ >= 7 const int mask = (1<<maskLen)-1; if ((h == bits) && !l && (s != d.reg)) { MOV(AL, 0, d.reg, s); // component = packed; } else if ((h == bits) && l) { MOV(AL, 0, d.reg, reg_imm(s, LSR, l)); // component = packed >> l; } else if (!l && isValidImmediate(mask)) { AND(AL, 0, d.reg, s, imm(mask)); // component = packed & mask; } else if (!l && isValidImmediate(~mask)) { BIC(AL, 0, d.reg, s, imm(~mask)); // component = packed & mask; } else { UBFX(AL, d.reg, s, l, maskLen); // component = (packed & mask) >> l; } #else if (h != bits) { const int mask = ((1<<maskLen)-1) << l; if (isValidImmediate(mask)) { AND(AL, 0, d.reg, s, imm(mask)); // component = packed & mask; } else if (isValidImmediate(~mask)) { BIC(AL, 0, d.reg, s, imm(~mask)); // component = packed & mask; } else { MOV(AL, 0, d.reg, reg_imm(s, LSL, 32-h)); l += 32-h; h = 32; } s = d.reg; } if (l) { MOV(AL, 0, d.reg, reg_imm(s, LSR, l)); // component = packed >> l; s = d.reg; } if (s != d.reg) { MOV(AL, 0, d.reg, s); } #endif d.s = maskLen; }
void JitFragmentWriter::emitSetLocal(InternedString s, int vreg, bool set_closure, RewriterVar* v) { assert(vreg >= 0); if (set_closure) { call(false, (void*)ASTInterpreterJitInterface::setLocalClosureHelper, getInterp(), imm(vreg), #ifndef NDEBUG imm(asUInt(s).first), imm(asUInt(s).second), #else imm(asUInt(s)), #endif v); } else { vregs_array->setAttr(8 * vreg, v); } }
RewriterVar* JitFragmentWriter::emitCreateSet(const llvm::ArrayRef<RewriterVar*> values) { auto num = values.size(); if (num == 0) return call(false, (void*)createSet); else return call(false, (void*)createSetHelper, imm(num), allocArgs(values)); }
static void addi(struct PPCDisasm *dp,ppc_word in,const char *ext) { if ((in&0x08000000) && !PPCGETA(in)) { sprintf(dp->opcode,"l%s",ext); /* li, lis */ if(!strcmp(ext, "i")) imm(dp,in,0,3,1); else imm(dp,in,1,3,1); } else { sprintf(dp->opcode,"%s%s",(in&0x8000)?"sub":"add",ext); if (in & 0x8000) in = (in^0xffff) + 1; imm(dp,in,1,0,0); } }
RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, int slot_size, AST* ast_node, TypeRecorder* type_recorder) { RewriterVar::SmallVector args_vec(args.begin(), args.end()); #if ENABLE_BASELINEJIT_ICS RewriterVar* result = createNewVar(); int args_size = args.size(); RewriterVar** _args = (RewriterVar**)regionAlloc(sizeof(RewriterVar*) * args_size); memcpy(_args, args.begin(), sizeof(RewriterVar*) * args_size); addAction([=]() { this->_emitPPCall(result, func_addr, llvm::ArrayRef<RewriterVar*>(_args, args_size), num_slots, slot_size, ast_node); }, args, ActionType::NORMAL); if (type_recorder) { RewriterVar* type_recorder_var = imm(type_recorder); RewriterVar* obj_cls_var = result->getAttr(offsetof(Box, cls)); addAction([=]() { _emitRecordType(type_recorder_var, obj_cls_var); }, { type_recorder_var, obj_cls_var }, ActionType::NORMAL); return result; } return result; #else assert(args_vec.size() < 7); return call(false, func_addr, args_vec); #endif }
void GGLAssembler::store(const pointer_t& addr, const pixel_t& s, uint32_t flags) { const int bits = addr.size; const int inc = (flags & WRITE_BACK)?1:0; switch (bits) { case 32: if (inc) STR(AL, s.reg, addr.reg, immed12_post(4)); else STR(AL, s.reg, addr.reg); break; case 24: // 24 bits formats are a little special and used only for RGB // 0x00BBGGRR is unpacked as R,G,B STRB(AL, s.reg, addr.reg, immed12_pre(0)); MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 8)); STRB(AL, s.reg, addr.reg, immed12_pre(1)); MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 8)); STRB(AL, s.reg, addr.reg, immed12_pre(2)); if (!(s.flags & CORRUPTIBLE)) { MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 16)); } if (inc) ADD(AL, 0, addr.reg, addr.reg, imm(3)); break; case 16: if (inc) STRH(AL, s.reg, addr.reg, immed8_post(2)); else STRH(AL, s.reg, addr.reg); break; case 8: if (inc) STRB(AL, s.reg, addr.reg, immed12_post(1)); else STRB(AL, s.reg, addr.reg); break; } }
void cgInitObjProps(IRLS& env, const IRInstruction* inst) { auto const cls = inst->extra<InitObjProps>()->cls; auto const obj = srcLoc(env, inst, 0).reg(); auto& v = vmain(env); // Set the attributes, if any. auto const odAttrs = cls->getODAttrs(); if (odAttrs) { static_assert(sizeof(ObjectData::Attribute) == 2, "Codegen expects 2-byte ObjectData attributes"); assertx(!(odAttrs & 0xffff0000)); v << orwim{odAttrs, obj[ObjectData::attributeOff()], v.makeReg()}; } // Initialize the properties. auto const nprops = cls->numDeclProperties(); if (nprops > 0) { if (cls->pinitVec().size() == 0) { // If the Class has no 86pinit property-initializer functions, we can // just copy the initial values from a data member on the Class. implInitObjPropsFast(v, env, inst, obj, cls, nprops); } else { // Load the Class's propInitVec from the target cache. We know it's // already been initialized as a pre-condition on this op. auto const propHandle = cls->propHandle(); assertx(rds::isNormalHandle(propHandle)); auto const propInitVec = v.makeReg(); auto const propData = v.makeReg(); v << load{Vreg(rvmtl())[propHandle], propInitVec}; v << load{propInitVec[Class::PropInitVec::dataOff()], propData}; auto const propsOff = sizeof(ObjectData) + cls->builtinODTailSize(); auto args = argGroup(env, inst) .addr(obj, safe_cast<int32_t>(propsOff)) .reg(propData); if (!cls->hasDeepInitProps()) { cgCallHelper(v, env, CallSpec::direct(memcpy), kVoidDest, SyncOptions::None, args.imm(cellsToBytes(nprops))); } else { cgCallHelper(v, env, CallSpec::direct(deepInitHelper), kVoidDest, SyncOptions::None, args.imm(nprops)); } } } }
static int src1 (FILE *file, struct brw_instruction *inst) { if (inst->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE) return imm (file, inst->bits1.da1.src1_reg_type, inst); else if (inst->header.access_mode == BRW_ALIGN_1) { if (inst->bits3.da1.src1_address_mode == BRW_ADDRESS_DIRECT) { return src_da1 (file, inst->bits1.da1.src1_reg_type, inst->bits1.da1.src1_reg_file, inst->bits3.da1.src1_vert_stride, inst->bits3.da1.src1_width, inst->bits3.da1.src1_horiz_stride, inst->bits3.da1.src1_reg_nr, inst->bits3.da1.src1_subreg_nr, inst->bits3.da1.src1_abs, inst->bits3.da1.src1_negate); } else { return src_ia1 (file, inst->bits1.ia1.src1_reg_type, inst->bits1.ia1.src1_reg_file, inst->bits3.ia1.src1_indirect_offset, inst->bits3.ia1.src1_subreg_nr, inst->bits3.ia1.src1_negate, inst->bits3.ia1.src1_abs, inst->bits3.ia1.src1_address_mode, inst->bits3.ia1.src1_horiz_stride, inst->bits3.ia1.src1_width, inst->bits3.ia1.src1_vert_stride); } } else { if (inst->bits3.da16.src1_address_mode == BRW_ADDRESS_DIRECT) { return src_da16 (file, inst->bits1.da16.src1_reg_type, inst->bits1.da16.src1_reg_file, inst->bits3.da16.src1_vert_stride, inst->bits3.da16.src1_reg_nr, inst->bits3.da16.src1_subreg_nr, inst->bits3.da16.src1_abs, inst->bits3.da16.src1_negate, inst->bits3.da16.src1_swz_x, inst->bits3.da16.src1_swz_y, inst->bits3.da16.src1_swz_z, inst->bits3.da16.src1_swz_w); } else { string (file, "Indirect align16 address mode not supported"); return 1; } } }
void SourceAssembler::add_using_gp(Register reg, const char *name, Condition cond) { int offset = find_gp_offset(name); if (is_rotated_imm(offset)) { eol_comment(name); add(reg, gp, imm(offset), cond); } else { char buff[128]; jvm_sprintf(buff, "slow add_gp_imm %s %d", name, offset); eol_comment(buff); offset -= 1024; GUARANTEE(is_rotated_imm(1024), "sanity"); GUARANTEE(is_rotated_imm(offset), "sanity"); add(reg, gp, imm(1024), cond); add(reg, reg, imm(offset), cond); } }
RewriterVar* JitFragmentWriter::emitCreateDict(const llvm::ArrayRef<RewriterVar*> keys, const llvm::ArrayRef<RewriterVar*> values) { assert(keys.size() == values.size()); if (keys.empty()) return call(false, (void*)createDict); else return call(false, (void*)createDictHelper, imm(keys.size()), allocArgs(keys), allocArgs(values)); }
void InterpreterStubs::generate_current_thread_to_primordial() { Segment seg(this, code_segment, "Current thread to primordial"); bind_global("current_thread_to_primordial"); comment("Set up global pointer, as we can be called from C code"); ldr_gp_base(gp); bind_global("current_thread_to_primordial_fast"); // We're never going to return to this thread, so it doesn't matter if // it doesn't look like a stopped Java thread anymore. get_primordial_sp(sp); comment("restore permanent registers (including return address)"); ldr(lr, imm_index(sp, BytesPerWord, post_indexed)); ldmfd(sp, range(r3, r11), writeback); jmpx(lr); if (GenerateDebugAssembly) { bind_local("interpreter_bkpt"); get_gp_bytecode_counter(tmp3); add(tmp3, tmp3, imm(1)); set_gp_bytecode_counter(tmp3); mov(pc, reg(tmp0)); } #if ENABLE_XSCALE_WMMX_TIMER_TICK && !ENABLE_TIMER_THREAD // set timer_tick from WMMX wCASF register comment("wmmx_set_timer_tick to set timer_tick from WMMX register"); bind_global("wmmx_set_timer_tick"); // tmrc(r2, wCASF); define_long(0xEE132110); mvn(r3, imm(4) ); andr(r2, r2, reg(r3) ); // tmcr(wCASF, r2); define_long(0xEE032110); jmpx(lr); // clear timer_tick from WMMX wCASF register comment("wmmx_set_timer_tick to clear timer_tick from WMMX register"); bind_global("wmmx_clear_timer_tick"); define_long(0xEE100060); // wcmpgtub(wR0, wR0, wR0); jmpx(lr); #endif // ENABLE_XSCALE_WMMX_TIMER_TICK && !ENABLE_TIMER_THREAD }
static PyObject* MemoryAccess_getScale(PyObject* self, PyObject* noarg) { try { triton::arch::Immediate imm(PyMemoryAccess_AsMemoryAccess(self)->getScale()); return PyImmediate(imm); } catch (const triton::exceptions::Exception& e) { return PyErr_Format(PyExc_TypeError, "%s", e.what()); } }
static PyObject* MemoryOperand_getScale(PyObject* self, PyObject* noarg) { try { triton::arch::ImmediateOperand imm(PyMemoryOperand_AsMemoryOperand(self)->getScale()); return PyImmediateOperand(imm); } catch (const std::exception& e) { return PyErr_Format(PyExc_TypeError, "%s", e.what()); } }
RewriterVar* JitFragmentWriter::emitRuntimeCall(AST_expr* node, RewriterVar* obj, ArgPassSpec argspec, const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names) { TypeRecorder* type_recorder = getTypeRecorderForNode(node); #if ENABLE_BASELINEJIT_ICS RewriterVar* argspec_var = imm(argspec.asInt()); RewriterVar::SmallVector call_args; call_args.push_back(obj); call_args.push_back(argspec_var); call_args.push_back(args.size() > 0 ? args[0] : imm(0ul)); call_args.push_back(args.size() > 1 ? args[1] : imm(0ul)); call_args.push_back(args.size() > 2 ? args[2] : imm(0ul)); if (args.size() > 3) { RewriterVar* scratch = allocate(args.size() - 3); for (int i = 0; i < args.size() - 3; ++i) scratch->setAttr(i * sizeof(void*), args[i + 3]); call_args.push_back(scratch); } else call_args.push_back(imm(0ul)); if (keyword_names) call_args.push_back(imm(keyword_names)); return emitPPCall((void*)runtimeCall, call_args, 2, 640, type_recorder); #else RewriterVar* argspec_var = imm(argspec.asInt()); RewriterVar* keyword_names_var = keyword_names ? imm(keyword_names) : nullptr; RewriterVar* args_array = nullptr; if (args.size()) { args_array = allocArgs(args); } else RELEASE_ASSERT(!keyword_names_var, "0 args but keyword names are set"); RewriterVar::SmallVector call_args; call_args.push_back(obj); call_args.push_back(argspec_var); call_args.push_back(imm(type_recorder)); if (args_array) call_args.push_back(args_array); if (keyword_names_var) call_args.push_back(keyword_names_var); return call(false, (void*)runtimeCallHelper, call_args); #endif }
void test_instructions_for_if() { asm_p as = &(asm_t){ 0 }; as_new(as); asm_jump_slot_t to_false_case, to_end; as_mov(as, RAX, imm(0)); as_cmp(as, RAX, imm(0)); to_false_case = as_jmp_cc(as, CC_NOT_EQUAL, 0); as_mov(as, R15, imm(43)); to_end = as_jmp(as, reld(0)); as_mark_jmp_slot_target(as, to_false_case); as_mov(as, R15, imm(17)); as_mark_jmp_slot_target(as, to_end); as_mov(as, RAX, imm(60)); as_mov(as, RDI, R15); as_syscall(as); as_save_elf(as, "test_instructions_for_if_true.elf"); as_clear(as); as_mov(as, RAX, imm(5)); as_cmp(as, RAX, imm(0)); to_false_case = as_jmp_cc(as, CC_NOT_EQUAL, 0); as_mov(as, R15, imm(43)); to_end = as_jmp(as, reld(0)); as_mark_jmp_slot_target(as, to_false_case); as_mov(as, R15, imm(17)); as_mark_jmp_slot_target(as, to_end); as_mov(as, RAX, imm(60)); as_mov(as, RDI, R15); as_syscall(as); as_save_elf(as, "test_instructions_for_if_false.elf"); as_destroy(as); int status_code; status_code = run_and_delete("test_instructions_for_if_true.elf", "./test_instructions_for_if_true.elf", NULL); st_check_int(status_code, 43); status_code = run_and_delete("test_instructions_for_if_false.elf", "./test_instructions_for_if_false.elf", NULL); st_check_int(status_code, 17); }
int main(){ Program prog("src/examples/recette.s"); Operand *Op1,*Op2, *Op3, *Op4, *Op5,*Op6; OPRegister registr("$5",5,Src); OPRegister registr0("$5",5,Dst); OPRegister registr1("$6",6,Dst); OPRegister registr2("$0",0,Src); OPRegister registr3("$6",6,Src); OPRegister registr4("$4",4,Dst); OPRegister registr5("$4",4,Src); OPImmediate imm("0xFFFF"); Directive dir("# Code avec des Nor"); Op1= ®istr; Op2= ®istr0; Op3= ®istr1; Op4= ®istr2; Op5= ®istr3; Op6= ®istr4; Line *ligne; prog.display(); prog.del_line(0); ligne = prog.find_line(0); Instruction *inst = dynamic_cast< Instruction * > (ligne); inst->set_opcode(lui); inst->set_op1(Op6); inst->set_op2(&imm); inst->set_op3(NULL); inst->set_number_oper(2); ligne=prog.find_line(1); Instruction *ins2 = dynamic_cast< Instruction * > (ligne); ins2->set_opcode(and_); Instruction ins3("ori $4,$4,0xFFFF",ori,R, ALU,Op6,®istr5,&imm,3); Instruction ins4("xor $5,$4,$0",xor_,R, ALU,Op1,®istr5,Op4,3); Instruction ins5("xor $4,$5,$6",xor_,R, ALU,Op3,®istr5,Op4,3); prog.add_line_at(&ins3,1); prog.add_line_at(&ins4,2); prog.add_line_at(&ins5,3); prog.display(); }
static void trapi(struct DisasmPara_PPC *dp,ppc_word in,unsigned char dmode) { char *cnd; if (cnd = trap_condition[PPCGETD(in)]) { dp->flags |= dmode; sprintf(dp->opcode,"t%c%s",dmode?'d':'w',cnd); imm(dp,in,0,2); } else ill(dp,in); }
void X86Compiler::_emitJcc(uint32_t code, const Label* label, uint32_t hint) { if (hint == kCondHintNone) { _emitInstruction(code, label); } else { Imm imm(hint); _emitInstruction(code, label, &imm); } }
void test_write_elf() { asm_p as = &(asm_t){ 0 }; as_new(as); const char* text_ptr = "Hello World!\n"; size_t text_len = strlen(text_ptr); size_t text_vaddr = as_data(as, text_ptr, text_len); as_mov(as, RAX, imm(1)); // wirte as_mov(as, RDI, imm(1)); // stdout as_mov(as, RSI, imm(text_vaddr)); // text ptr as_mov(as, RDX, imm(text_len)); // text len as_syscall(as); as_mov(as, RAX, imm(60)); // exit as_mov(as, RDI, imm(1)); // exit code as_syscall(as); as_save_elf(as, "test_write_elf.elf"); as_destroy(as); char* output = NULL; int status_code = run_and_delete("test_write_elf.elf", "./test_write_elf.elf", &output); st_check_int(status_code, 1); st_check_str(output, text_ptr); free(output); }
void handle(int pass, instruction_t i, void (*emit)(int, instruction_t)) { if (i.operand_count != 0) { fprintf(stderr, "Invalid arguments for 'rdc'\n"); exit(EXIT_FAILURE); } else { emit(pass, ins("mov", 2, imm(REQ_READ_CHAR), reg(REG_IO))); } }
RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, int slot_size, TypeRecorder* type_recorder) { RewriterVar::SmallVector args_vec(args.begin(), args.end()); #if ENABLE_BASELINEJIT_ICS RewriterVar* result = createNewVar(); addAction([=]() { this->_emitPPCall(result, func_addr, args_vec, num_slots, slot_size); }, args, ActionType::NORMAL); if (type_recorder) return call(false, (void*)recordType, imm(type_recorder), result); return result; #else assert(args_vec.size() < 7); return call(false, func_addr, args_vec); #endif }
virtual V m_bang() { if(!ref.Ok() || !ref.Check()) { /* if(!frms) post("%s - No length defined!",thisName()); else */ { ImmBuf ibuf(frms,zero); Vasp ret(frms,Vasp::Ref(ibuf)); ToOutVasp(0,ret); } } else if(ref.Vectors() > 1) post("%s - More than one vector in vasp!",thisName()); else { VBuffer *buf = ref.Buffer(0); const I len = buf->Length(),chns = buf->Channels(); // size of memory reservation (at least frms samples) const I rlen = frms > len?frms:len; ImmBuf imm(rlen,false); BS *dst = imm.Pointer(); const BS *src = buf->Pointer(); // post("!copy: src: %p,%i,%i -> dst: %p,%i",src,len,chns,dst,rlen); register int i; _DE_LOOP(i,len, ( dst[i] = *src,src += chns ) ) if(zero && rlen > len) ZeroSamples(dst+len,rlen-len); Vasp::Ref vr(imm); // post("!vr: %s,%i",vr.Ok()?vr.Symbol().Name():"***",vr.Offset()); Vasp ret(len,vr); ToOutVasp(0,ret); delete buf; } }