void Assembler::li64 (const Reg64& rt, int64_t imm64, bool fixedSize) { // li64 always emits 5 instructions i.e. 20 bytes of instructions. // Assumes that 0 bytes will be missing in the end. uint8_t missing = 0; // for assert purposes DEBUG_ONLY CodeAddress li64StartPos = frontier(); if (HPHP::jit::deltaFits(imm64, HPHP::sz::word)) { // immediate has only low 16 bits set, use simple load immediate li(rt, static_cast<int16_t>(imm64)); if (imm64 & (1ULL << 15) && !(imm64 & (1ULL << 16))) { // clear extended sign that should not be set // (32bits number. Sets the 16th bit but not the 17th, it's not negative!) clrldi(rt, rt, 48); missing = kLi64Len - 2 * instr_size_in_bytes; } else { missing = kLi64Len - 1 * instr_size_in_bytes; } } else if (HPHP::jit::deltaFits(imm64, HPHP::sz::dword)) { // immediate has only low 32 bits set lis(rt, static_cast<int16_t>(imm64 >> 16)); ori(rt, rt, static_cast<int16_t>(imm64 & UINT16_MAX)); if (imm64 & (1ULL << 31) && !(imm64 & (1ULL << 32))) { // clear extended sign // (64bits number. Sets the 32th bit but not the 33th, it's not negative!) clrldi(rt, rt, 32); missing = kLi64Len - 3 * instr_size_in_bytes; } else { missing = kLi64Len - 2 * instr_size_in_bytes; } } else if (imm64 >> 48 == 0) {
address AbstractInterpreterGenerator::generate_result_handler_for(BasicType type) { // // Registers alive // R3_RET // LR // // Registers updated // R3_RET // Label done; address entry = __ pc(); switch (type) { case T_BOOLEAN: // convert !=0 to 1 __ neg(R0, R3_RET); __ orr(R0, R3_RET, R0); __ srwi(R3_RET, R0, 31); break; case T_BYTE: // sign extend 8 bits __ extsb(R3_RET, R3_RET); break; case T_CHAR: // zero extend 16 bits __ clrldi(R3_RET, R3_RET, 48); break; case T_SHORT: // sign extend 16 bits __ extsh(R3_RET, R3_RET); break; case T_INT: // sign extend 32 bits __ extsw(R3_RET, R3_RET); break; case T_LONG: break; case T_OBJECT: // unbox result if not null __ cmpdi(CCR0, R3_RET, 0); __ beq(CCR0, done); __ ld(R3_RET, 0, R3_RET); __ verify_oop(R3_RET); break; case T_FLOAT: break; case T_DOUBLE: break; case T_VOID: break; default: ShouldNotReachHere(); } __ BIND(done); __ blr(); return entry; }