int asm_sparc_fcmpd(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op2_table[opcode.op3]; ins->type = ASM_TYPE_COMPARISON | ASM_TYPE_WRITEFLAG; ins->flagswritten = ASM_SP_FLAG_FCC0 << opcode.cc; ins->instr = inter->fcmp_table[(opcode.opf & 0x1f) - 16]; ins->nb_op = 3; ins->op[0].baser = ((opcode.rs2 & 1) << 5) | (opcode.rs2 & 0x1E); asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_FREGISTER, ins); ins->op[1].baser = ((opcode.rs1 & 1) << 5) | (opcode.rs1 & 0x1E); asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_FREGISTER, ins); ins->op[2].baser = opcode.cc; asm_sparc_op_fetch(&ins->op[2], buf, ASM_SP_OTYPE_CC, ins); return 4; }
int asm_sparc_ldd(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op3_table[opcode.op3]; ins->type = ASM_TYPE_LOAD | ASM_TYPE_ASSIGN; ins->nb_op = 2; ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_REGISTER, ins); if (opcode.i) { ins->op[1].baser = opcode.rs1; ins->op[1].imm = opcode.imm; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_IMM_ADDRESS, ins); } else { ins->op[1].baser = opcode.rs1; ins->op[1].indexr = opcode.rs2; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_REG_ADDRESS, ins); } return 4; }
int asm_sparc_andncc(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op2_table[opcode.op3]; ins->arith = ASM_ARITH_AND | ASM_ARITH_NOT; ins->type = ASM_TYPE_ARITH | ASM_TYPE_WRITEFLAG; ins->flagswritten = ASM_SP_FLAG_C | ASM_SP_FLAG_V | ASM_SP_FLAG_Z | ASM_SP_FLAG_N; ins->nb_op = 3; ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_REGISTER, ins); ins->op[2].baser = opcode.rs1; asm_sparc_op_fetch(&ins->op[2], buf, ASM_SP_OTYPE_REGISTER, ins); if (opcode.i == 0) { ins->op[1].baser = opcode.rs2; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_REGISTER, ins); } else { ins->op[1].imm = opcode.imm; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_IMMEDIATE, ins); } return 4; }
int asm_sparc_sethi(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_branch opcode; sparc_convert_branch(&opcode, buf); ins->type = ASM_TYPE_ASSIGN; if (!opcode.rd && !opcode.imm) { ins->instr = ASM_SP_NOP; ins->type = ASM_TYPE_NOP; ins->nb_op = 0; } else { ins->instr = ASM_SP_SETHI; ins->nb_op = 2; ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_REGISTER, ins); ins->op[1].imm = opcode.imm; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_SETHI, ins); } return 4; }
int asm_sparc_rdpr(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op2_table[opcode.op3]; ins->type = ASM_TYPE_ASSIGN; if (opcode.rs1 < ASM_PREG_BAD16 || opcode.rs1 > ASM_PREG_BAD30) { ins->nb_op = 2; ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_REGISTER, ins); ins->op[1].baser = opcode.rs1; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_PREGISTER, ins); } else ins->instr = ASM_SP_BAD; return 4; }
int asm_sparc_stqfa(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op3_table[opcode.op3]; ins->type = ASM_TYPE_STORE | ASM_TYPE_ASSIGN; ins->nb_op = 2; if (opcode.i) { ins->op[0].baser = opcode.rs1; ins->op[0].imm = opcode.imm; ins->op[0].address_space = -1; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_IMM_ADDRESS, ins); } else { ins->op[0].baser = opcode.rs1; ins->op[0].indexr = opcode.rs2; ins->op[0].address_space = opcode.none; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_REG_ADDRESS, ins); } ins->op[1].baser = ((opcode.rd & 1) << 5) | (opcode.rd & 0x1E); asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_FREGISTER, ins); return 4; }
int asm_sparc_orn(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op2_table[opcode.op3]; ins->type = ASM_TYPE_LOAD; ins->nb_op = 3; ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_REGISTER, ins); ins->op[2].baser = opcode.rs1; asm_sparc_op_fetch(&ins->op[2], buf, ASM_SP_OTYPE_REGISTER, ins); if (opcode.i == 0) { ins->op[1].baser = opcode.rs2; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_REGISTER, ins); } else { ins->op[1].imm = opcode.imm; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_IMMEDIATE, ins); } return 4; }
int asm_sparc_or(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op2_table[opcode.op3]; ins->arith = ASM_ARITH_OR; ins->type = ASM_TYPE_ARITH; ins->nb_op = 3; ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_REGISTER, ins); ins->op[2].baser = opcode.rs1; asm_sparc_op_fetch(&ins->op[2], buf, ASM_SP_OTYPE_REGISTER, ins); if (opcode.i == 0) { ins->op[1].baser = opcode.rs2; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_REGISTER, ins); } else { ins->op[1].imm = opcode.imm; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_IMMEDIATE, ins); } if (asm_config_get_synthinstr()) { if (ins->op[0].baser == ins->op[2].baser) { ins->instr = ASM_SP_BSET; ins->nb_op = 2; ins->type = ASM_TYPE_BITSET; } else if (ins->op[2].baser == ASM_REG_G0) { if (ins->op[1].content == ASM_SP_OTYPE_REGISTER && ins->op[1].baser == ASM_REG_G0) { ins->instr = ASM_SP_CLR; ins->nb_op = 1; } else { ins->instr = ASM_SP_MOV; ins->nb_op = 2; ins->type = ASM_TYPE_ASSIGN; } } } return 4; }
int asm_sparc_wr(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op2_table[opcode.op3]; ins->type = ASM_TYPE_ASSIGN; if (opcode.rd == 1) ins->instr = ASM_SP_BAD; else if (opcode.rd == 15) { /* SIR */ ins->instr = ASM_SP_SIR; ins->type = ASM_TYPE_INT; ins->nb_op = 1; ins->op[0].imm = opcode.imm; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_IMMEDIATE, ins); } else { /* WR */ ins->nb_op = 3; if (opcode.rd == 2) { /* WRCCR overwrites the condition codes */ ins->type |= ASM_TYPE_WRITEFLAG; ins->flagswritten = ASM_SP_FLAG_C | ASM_SP_FLAG_V | ASM_SP_FLAG_Z | ASM_SP_FLAG_N; } if (opcode.rd == 4 || opcode.rd == 5) /* can't write PC or TICK */ ins->op[0].baser = ASM_SREG_BAD; else ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_SREGISTER, ins); ins->op[2].baser = opcode.rs1; asm_sparc_op_fetch(&ins->op[2], buf, ASM_SP_OTYPE_REGISTER, ins); if (opcode.i == 0) { ins->op[1].baser = opcode.rs2; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_REGISTER, ins); } else { ins->op[1].imm = opcode.imm; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_IMMEDIATE, ins); } if (ins->op[0].baser == ASM_SREG_Y && ins->op[2].baser == ASM_REG_G0) { ins->instr = ASM_SP_MOV; ins->nb_op = 2; } } return 4; }
int asm_sparc_bicc(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_branch opcode; struct s_asm_proc_sparc *inter; sparc_convert_branch(&opcode, buf); inter = proc->internals; ins->instr = inter->bcc_table[opcode.cond]; if (ins->instr == ASM_SP_BA) ins->type = ASM_TYPE_BRANCH; else if (ins->instr == ASM_SP_BN) ins->type = ASM_TYPE_NOP; else ins->type = ASM_TYPE_BRANCH | ASM_TYPE_CONDCONTROL; ins->nb_op = 1; ins->op[0].imm = opcode.imm; ins->annul = opcode.a; ins->prediction = 1; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_DISPLACEMENT, ins); return 4; }
int asm_sparc_rd(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->instr = inter->op2_table[opcode.op3]; ins->type = ASM_TYPE_ASSIGN; if (opcode.rs1 != 15) { /* RD*(-PR) */ ins->nb_op = 2; ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_REGISTER, ins); ins->op[1].baser = opcode.rs1; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_SREGISTER, ins); if (ins->op[0].baser == ASM_SREG_Y) { ins->instr = ASM_SP_MOV; } } else { if (opcode.rd != 0) ins->instr = ASM_SP_BAD; else if (opcode.i == 0) { /* STBAR */ ins->type = ASM_TYPE_OTHER; ins->instr = ASM_SP_STBAR; } else if (opcode.i == 1) { /* MEMBAR */ ins->instr = ASM_SP_MEMBAR; ins->type = ASM_TYPE_OTHER; ins->nb_op = 1; /* operand = cmask OR mmask */ ins->op[0].imm = ((opcode.imm & 0x70) >> 4) | (opcode.imm & 0xf); asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_IMMEDIATE, ins); } }
int asm_sparc_fmovdcc(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->type = ASM_TYPE_ASSIGN | ASM_TYPE_READFLAG; if (opcode.opf_cc < 4) { ins->instr = inter->fmovfcc_table[(((opcode.opf & 0x1f) - 1) * 8) + opcode.cond]; ins->flagsread = ASM_SP_FLAG_FCC0 << opcode.opf_cc; } else if (opcode.opf_cc == 4 || opcode.opf_cc == 6) { ins->instr = inter->fmovcc_table[(((opcode.opf & 0x1f) - 1) * 8) + opcode.cond]; ins->flagsread = ASM_SP_FLAG_C | ASM_SP_FLAG_V | ASM_SP_FLAG_N | ASM_SP_FLAG_Z; } else { ins->instr = ASM_SP_BAD; return 4; } ins->nb_op = 3; ins->op[0].baser = ((opcode.rd & 1) << 5) | (opcode.rd & 0x1E); asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_FREGISTER, ins); ins->op[1].baser = ((opcode.rs2 & 1) << 5) | (opcode.rs2 & 0x1E); asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_FREGISTER, ins); ins->op[2].baser = opcode.opf_cc; asm_sparc_op_fetch(&ins->op[2], buf, ASM_SP_OTYPE_CC, ins); return 4; }
int asm_sparc_bpcc(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_pbranch opcodep; struct s_asm_proc_sparc *inter; sparc_convert_pbranch(&opcodep, buf); inter = proc->internals; ins->instr = inter->bcc_table[opcodep.cond]; if (ins->instr == ASM_SP_BA) ins->type = ASM_TYPE_BRANCH; else if (ins->instr == ASM_SP_BN) ins->type = ASM_TYPE_NOP; else ins->type = ASM_TYPE_BRANCH | ASM_TYPE_CONDCONTROL; ins->nb_op = 2; ins->op[0].imm = opcodep.imm; ins->op[1].baser = opcodep.cc + 4; ins->annul = opcodep.a; ins->prediction = opcodep.p; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_DISPLACEMENT, ins); asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_CC, ins); if (ins->instr == ASM_SP_BN && ins->annul && ins->prediction && ins->op[1].baser == ASM_SP_XCC) { ins->instr = ASM_SP_IPREFETCH; ins->nb_op = 1; ins->type = ASM_TYPE_NONE; } return 4; }
int asm_sparc_fmovsr(asm_instr * ins, u_char * buf, u_int len, asm_processor * proc) { struct s_decode_format3 opcode; struct s_asm_proc_sparc *inter; sparc_convert_format3(&opcode, buf); inter = proc->internals; ins->type = ASM_TYPE_ASSIGN | ASM_TYPE_COMPARISON; ins->instr = inter->fmovr_table[(((opcode.opf & 0x1f) - 6) * 8) + opcode.rcond]; ins->nb_op = 3; ins->op[0].baser = opcode.rd; asm_sparc_op_fetch(&ins->op[0], buf, ASM_SP_OTYPE_FREGISTER, ins); ins->op[1].baser = opcode.rs2; asm_sparc_op_fetch(&ins->op[1], buf, ASM_SP_OTYPE_FREGISTER, ins); ins->op[2].baser = opcode.rs1; asm_sparc_op_fetch(&ins->op[2], buf, ASM_SP_OTYPE_REGISTER, ins); return 4; }