void simu_pc(struct pt_regs *regs, union loongarch_instruction insn)
{ unsignedlong pc = regs->csr_era; unsignedint rd = insn.reg1i20_format.rd; unsignedint imm = insn.reg1i20_format.immediate;
if (pc & 3) {
pr_warn("%s: invalid pc 0x%lx\n", __func__, pc); return;
}
switch (insn.reg1i20_format.opcode) { case pcaddi_op:
regs->regs[rd] = pc + sign_extend64(imm << 2, 21); break; case pcaddu12i_op:
regs->regs[rd] = pc + sign_extend64(imm << 12, 31); break; case pcaddu18i_op:
regs->regs[rd] = pc + sign_extend64(imm << 18, 37); break; case pcalau12i_op:
regs->regs[rd] = pc + sign_extend64(imm << 12, 31);
regs->regs[rd] &= ~((1 << 12) - 1); break; default:
pr_info("%s: unknown opcode\n", __func__); return;
}
regs->csr_era += LOONGARCH_INSN_SIZE;
}
void simu_branch(struct pt_regs *regs, union loongarch_instruction insn)
{ unsignedint imm, imm_l, imm_h, rd, rj; unsignedlong pc = regs->csr_era;
if (pc & 3) {
pr_warn("%s: invalid pc 0x%lx\n", __func__, pc); return;
}
imm_l = insn.reg0i26_format.immediate_l;
imm_h = insn.reg0i26_format.immediate_h; switch (insn.reg0i26_format.opcode) { case b_op:
regs->csr_era = pc + sign_extend64((imm_h << 16 | imm_l) << 2, 27); return; case bl_op:
regs->csr_era = pc + sign_extend64((imm_h << 16 | imm_l) << 2, 27);
regs->regs[1] = pc + LOONGARCH_INSN_SIZE; return;
}
imm_l = insn.reg1i21_format.immediate_l;
imm_h = insn.reg1i21_format.immediate_h;
rj = insn.reg1i21_format.rj; switch (insn.reg1i21_format.opcode) { case beqz_op: if (regs->regs[rj] == 0)
regs->csr_era = pc + sign_extend64((imm_h << 16 | imm_l) << 2, 22); else
regs->csr_era = pc + LOONGARCH_INSN_SIZE; return; case bnez_op: if (regs->regs[rj] != 0)
regs->csr_era = pc + sign_extend64((imm_h << 16 | imm_l) << 2, 22); else
regs->csr_era = pc + LOONGARCH_INSN_SIZE; return;
}
imm = insn.reg2i16_format.immediate;
rj = insn.reg2i16_format.rj;
rd = insn.reg2i16_format.rd; switch (insn.reg2i16_format.opcode) { case beq_op: if (regs->regs[rj] == regs->regs[rd])
regs->csr_era = pc + sign_extend64(imm << 2, 17); else
regs->csr_era = pc + LOONGARCH_INSN_SIZE; break; case bne_op: if (regs->regs[rj] != regs->regs[rd])
regs->csr_era = pc + sign_extend64(imm << 2, 17); else
regs->csr_era = pc + LOONGARCH_INSN_SIZE; break; case blt_op: if ((long)regs->regs[rj] < (long)regs->regs[rd])
regs->csr_era = pc + sign_extend64(imm << 2, 17); else
regs->csr_era = pc + LOONGARCH_INSN_SIZE; break; case bge_op: if ((long)regs->regs[rj] >= (long)regs->regs[rd])
regs->csr_era = pc + sign_extend64(imm << 2, 17); else
regs->csr_era = pc + LOONGARCH_INSN_SIZE; break; case bltu_op: if (regs->regs[rj] < regs->regs[rd])
regs->csr_era = pc + sign_extend64(imm << 2, 17); else
regs->csr_era = pc + LOONGARCH_INSN_SIZE; break; case bgeu_op: if (regs->regs[rj] >= regs->regs[rd])
regs->csr_era = pc + sign_extend64(imm << 2, 17); else
regs->csr_era = pc + LOONGARCH_INSN_SIZE; break; case jirl_op:
regs->csr_era = regs->regs[rj] + sign_extend64(imm << 2, 17);
regs->regs[rd] = pc + LOONGARCH_INSN_SIZE; break; default:
pr_info("%s: unknown opcode\n", __func__); return;
}
}
bool insns_not_supported(union loongarch_instruction insn)
{ switch (insn.reg3_format.opcode) { case amswapw_op ... ammindbdu_op:
pr_notice("atomic memory access instructions are not supported\n"); returntrue; case scq_op:
pr_notice("sc.q instruction is not supported\n"); returntrue;
}
switch (insn.reg2i14_format.opcode) { case llw_op: case lld_op: case scw_op: case scd_op:
pr_notice("ll and sc instructions are not supported\n"); returntrue;
}
switch (insn.reg2_format.opcode) { case llacqw_op: case llacqd_op: case screlw_op: case screld_op:
pr_notice("llacq and screl instructions are not supported\n"); returntrue;
}
switch (insn.reg1i21_format.opcode) { case bceqz_op:
pr_notice("bceqz and bcnez instructions are not supported\n"); returntrue;
}
returnfalse;
}
bool insns_need_simulation(union loongarch_instruction insn)
{ if (is_pc_ins(&insn)) returntrue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.