void bgezall() { // if (_rs.0-63 >= 0) delayslot = instaddr + 4 + _offset * 4 enum { _jump, _end }; mov32_mem_imm32((u32)&g_cpu->m_ra.d[0], g_cpu->m_recompiling_ee_va + 8); mov32_mem_imm32((u32)&g_cpu->m_ra.d[1], 0x00000000); // 符号ビットが0ならジャンプ mov32_eax_mem(_GPR_D(_rs, 1)); tst32_reg_reg(_eax, _eax); jns(_jump); // 分岐しない場合、次の遅延スロットの命令を実行しない mov8_mem_imm8((u32)&g_cpu->m_null_current_inst, 1); jmp(_end); LABEL_DEF(_jump); mov32_reg_imm32(_eax, (g_cpu->m_recompiling_ee_va + 4) + _offset * 4); mov32_mem_eax((u32)&g_cpu->m_ee_jump_addr); #if defined _DEBUGGER push_reg(_eax); // eaxはジャンプ先 mov32_reg_imm32(_eax, (u32)Debugger::callStackPush); call_reg(_eax); pop_reg(_eax); mov32_reg_imm32(_eax, (u32)Debugger::jumpLogPush); call_reg(_eax); #endif LABEL_DEF(_end); }
void bltzal() { // if (_rs.0-63 < 0) delayslot = instaddr + 4 + _offset * 4 enum { _end }; mov32_mem_imm32((u32)&g_cpu->m_ra.d[0], g_cpu->m_recompiling_ee_va + 8); mov32_mem_imm32((u32)&g_cpu->m_ra.d[1], 0x00000000); // 符号ビットが0ならジャンプしない mov32_eax_mem(_GPR_D(_rs, 1)); tst32_reg_reg(_eax, _eax); jns(_end); mov32_reg_imm32(_eax, (g_cpu->m_recompiling_ee_va + 4) + _offset * 4); mov32_mem_eax((u32)&g_cpu->m_ee_jump_addr); #if defined _DEBUGGER push_reg(_eax); // eaxはジャンプ先 mov32_reg_imm32(_eax, (u32)Debugger::callStackPush); call_reg(_eax); pop_reg(_eax); mov32_reg_imm32(_eax, (u32)Debugger::jumpLogPush); call_reg(_eax); #endif LABEL_DEF(_end); }
// INS_CNV, DUP1, DUP2, DEL, INV void rsv_gen(FILE *msg, reg_t *rsv_reg) { char msg_line[1024]; _reg_t r; char chr[10]; int s,e,len; char type[10]; char xa[1024], ins_chr[10]; int ins_s, ins_e; int left=1, offset=0, right; while (fgets(msg_line, 1024, msg) != NULL) { sscanf(msg_line, "%s\t%d\t%d\t%d\t%s\t%[^\n]\n", chr, &s, &e, &len, type, xa); switch(type[2]) { case 'S': // INS sscanf(xa, "%s\t%d\t%d", ins_chr, &ins_s, &ins_e); right = s+offset; //M right //fprintf(stdout, "%s\t%d\t%d\t%d\t%s\n", chr, left, right, right-left+1, "MAT"); r.chr = get_chr(chr), strcpy(r.type, "MAT"); r.left = left, r.right = right, r.len = right-left+1, r.offset=offset; push_reg(rsv_reg, r); left=e+offset; //I left right=left+len-1; //I right //fprintf(stdout, "%s\t%d\t%d\t%d\t%s\n", chr, left, right, len, "INS"); r.chr = get_chr(chr), strcpy(r.type, "INS_CNV"); r.left = left, r.right = right, r.len = len, r.offset=offset; // ins_reg r.ins_chr = get_chr(ins_chr); r.ins_left = ins_s, r.ins_right = ins_e; push_reg(rsv_reg, r); left = e+offset+len; offset+=len; break; case 'P': // DUP (DUP1, DUP2, ...) right = s+offset; // M right r.chr = get_chr(chr), strcpy(r.type, "MAT"); r.left = left, r.right = right, r.len = right-left+1, r.offset=offset; push_reg(rsv_reg, r); left=e+offset; // P left right=left+len-1; // P right r.chr = get_chr(chr), strcpy(r.type, type); // DUP1, DUP2, ... r.left = left, r.right = right, r.len = len, r.offset=offset; // dup_reg r.ins_chr = get_chr(chr); r.ins_left = s-(len)/atoi(type+3)+1; r.ins_right = s; push_reg(rsv_reg, r); left = e+offset+len; offset+=len; break; case 'L': // DEL right = s+offset; //fprintf(stdout, "%s\t%d\t%d\t%d\t%s\n", chr, left, right, right-left+1, "MAT"); r.chr = get_chr(chr), strcpy(r.type, "MAT"); r.left = left, r.right = right, r.len = right-left+1, r.offset=offset; push_reg(rsv_reg, r); left=s+offset; offset-=len; right=e+offset; //fprintf(stdout, "%s\t%d\t%d\t%d\t%s\n", chr, left, right, len, "DEL"); r.chr = get_chr(chr), strcpy(r.type, "DEL"); r.left = left, r.right = right, r.len = len, r.offset=offset; push_reg(rsv_reg, r); left=right; break; case 'V': // INV right=s+offset; //M right //fprintf(stdout, "%s\t%d\t%d\t%d\t%s\n", chr, left, right, right-left+1, "MAT"); r.chr = get_chr(chr), strcpy(r.type, "MAT"); r.left = left, r.right = right, r.len = right-left+1, r.offset=offset; push_reg(rsv_reg, r); left=right+1; //V left right=e+offset-1;//V right //fprintf(stdout, "%s\t%d\t%d\t%d\t%s\n", chr, left, right, len, "INV"); r.chr = get_chr(chr), strcpy(r.type, "INV"); r.left = left, r.right = right, r.len = len, r.offset=offset; r.ins_left = s, r.ins_right = e; // inv_left, inv_right push_reg(rsv_reg, r); left=e+offset; //M left break; default: break; } //fprintf(stdout, "%s %d %d %d %s\n", chr, s, e, len, type); } right=CHR_MAX_LEN; len=right-left+1; //fprintf(stdout, "%s\t%d\t%d\t%d\t%s\n", chr, left, right, len, "MAT"); r.chr = get_chr(chr), strcpy(r.type, "MAT"); r.left = left, r.right = right, r.len = len, r.offset=offset; push_reg(rsv_reg, r); }
void whole_gen_core(reg_t *rsv_reg, FILE *wgsim, reg_t *who_reg) { int i; char msg_line[1024]; _reg_t r; char chr[10]; int s,e,len; char type[10]; int offset=0, /*next*/left=1, right; int cur_rsv_n = 0; _reg_t R_r, w_r; int indel=0; reg_t *cur, *next; //init cur/next cur = (reg_t*)malloc(sizeof(reg_t)); cur->reg_m = 100; cur->reg = (_reg_t*)malloc(100 * sizeof(_reg_t)); next = (reg_t*)malloc(sizeof(reg_t)); next->reg_m = 100; next->reg = (_reg_t*)malloc(100 * sizeof(_reg_t)); cur->reg_n = 0; next->reg_n = 0; // first wgsim-region, stored in next fgets(msg_line, 1024, wgsim); sscanf(msg_line, "%s\t%d\t%d\t%d\t%s\n", chr, &s, &e, &len, type); r.left = s, r.right = e, r.len = len, r.offset=0; r.chr=get_chr(chr), strcpy(r.type, type); push_reg(next, r); offset = 0; while (cur_rsv_n < rsv_reg->reg_n) { // clear cur cur->reg_n = 0; R_r = rsv_reg->reg[cur_rsv_n]; // find wgsim in the rsv-region, store in cur // until one wgsim outbound this rsv-reg, store in next if (next->reg_n>0 && R_r.type[2] != 'L') { // push next to cur, if necessary if (((next->reg[0].type[2] == 'S' || next->reg[0].type[2] == 'P') && next->reg[0].left <= rsv_reg->reg[cur_rsv_n].right) || (next->reg[0].type[2] == 'L' && next->reg[0].left < rsv_reg->reg[cur_rsv_n].right)) { // split wgsim, if it acrosses two RSV-reg if (next->reg[0].type[2] == 'L'&& next->reg[0].right > rsv_reg->reg[cur_rsv_n].right+1) { r.left = next->reg[0].left; r.right = rsv_reg->reg[cur_rsv_n].right+1; r.len = r.right-r.left+1; r.offset = 0; r.chr = next->reg[0].chr, strcpy(r.type, "DEL"); push_reg(cur, r); r.left = rsv_reg->reg[cur_rsv_n].right; r.right = next->reg[0].right; r.len = r.right-r.left+1; r.offset = 0; next->reg_n=0; push_reg(next, r); goto UPDATE; } push_reg(cur, next->reg[0]); next->reg_n = 0; // push wgsim to cur, if necessary // until push wgsim to next, or reach EOF in wgsim while (fgets(msg_line, 1024, wgsim) != NULL) { sscanf(msg_line, "%s\t%d\t%d\t%d\t%s\n", chr, &(r.left), &(r.right), &(r.len), r.type); r.chr = get_chr(chr); if (((r.type[2]=='S' || r.type[2]=='P') && r.left <= rsv_reg->reg[cur_rsv_n].right) || (r.type[2]=='L' && r.left < rsv_reg->reg[cur_rsv_n].right)) { // split wgsim, if necessary, same to upper if (r.type[2] == 'L' && r.right > rsv_reg->reg[cur_rsv_n].right+1) { left = r.left, right = r.right, len = r.len; r.left = left, r.right = rsv_reg->reg[cur_rsv_n].right+1; r.len = r.right-r.left+1; r.offset=0; push_reg(cur, r); r.left = rsv_reg->reg[cur_rsv_n].right; r.right = right; r.len = r.right - r.left + 1; push_reg(next, r); break; } push_reg(cur, r); } else { push_reg(next, r); break; } } } } UPDATE: // split cur_rsv, based on cur, push into whole_reg switch (R_r.type[2]) { case 'T': // MATCH left = R_r.left+offset; for (i = 0; i < cur->reg_n; ++i) { // push (left, cur.s) and (cur.s, cur.e) into whole_reg w_r = cur->reg[i]; switch (w_r.type[2]){ case 'S': // INS // (left, cur.s) r.left = left; r.right = w_r.left+offset; r.len = r.right-r.left+1; r.offset = R_r.offset+offset; r.wgsim_off = offset; r.chr = w_r.chr, strcpy(r.type, R_r.type); push_reg(who_reg, r); // (wgsim) r.left = w_r.right+offset; r.len = w_r.len; r.right = r.left+r.len-1; r.wgsim_off = offset; r.chr = w_r.chr, strcpy(r.type, "INS"); push_reg(who_reg, r); // set next-left left = r.right+1; offset += len; break; case 'L': // DEL // (left, cur.s) r.left = left; r.right = w_r.left+offset; r.len = r.right-r.left+1; r.offset = R_r.offset+offset; r.wgsim_off = offset; r.chr = w_r.chr, strcpy(r.type, R_r.type); push_reg(who_reg, r); // (cur.s, cur.e) r.left = w_r.left+offset; r.right = r.left+1; r.len = w_r.len; r.offset = R_r.offset+offset; r.wgsim_off = offset; r.chr = w_r.chr, strcpy(r.type, "DEL"); push_reg(who_reg, r); // next left left = r.right; offset -= w_r.len; break; default: break; } } // push (left, rsv.end) into whole_reg r.left = left; r.right = R_r.right+offset; r.len = r.right-r.left+1; r.offset = R_r.offset+offset; r.wgsim_off = offset; r.chr = R_r.chr, strcpy(r.type, R_r.type); push_reg(who_reg, r); break; case 'V': // INV indel = 0; for (i = 0; i < cur->reg_n; ++i) { // calculate whole-indels if (cur->reg[i].type[2] == 'S') // INS indel += (cur->reg[i].len); else if (cur->reg[i].type[2] == 'L') // DEL indel -= (cur->reg[i].len); else {fprintf(stderr, "[whole_gen] Error.\n"); exit(0);} } r.left = R_r.left + offset; r.len = R_r.len + indel; r.right = r.left + r.len - 1; r.offset = R_r.offset + offset; r.wgsim_off = offset; r.chr = R_r.chr, strcpy(r.type, R_r.type); r.ins_left = R_r.ins_left; r.ins_right = R_r.ins_right; push_reg(who_reg, r); offset += indel; break; case 'S': // INS case 'P': // DUP indel = 0; for (i = 0; i < cur->reg_n; ++i) { // calculate whole-indels if (cur->reg[i].type[2] == 'S') // INS indel += (cur->reg[i].len); else if (cur->reg[i].type[2] == 'L') // DEL indel -= (cur->reg[i].len); else {fprintf(stderr, "[whole_gen] Error.\n"); exit(0);} } r.left = R_r.left + offset; r.len = R_r.len + indel; if (r.len <=0 ) { fprintf(stderr, "[whole_gen] Error: indel >= RSV %s-len.\n", R_r.type); exit(0); } r.right = r.left + r.len - 1; r.offset = R_r.offset + offset; r.wgsim_off = offset; r.chr = R_r.chr, strcpy(r.type, R_r.type); r.ins_chr = R_r.ins_chr; r.ins_left = R_r.ins_left; r.ins_right = R_r.ins_right; push_reg(who_reg, r); offset += indel; break; case 'L': // DEL // no split r.left = R_r.left+offset; r.right = R_r.right+offset; r.len = R_r.len; r.offset = R_r.offset+offset; r.wgsim_off = offset; r.chr = R_r.chr, strcpy(r.type, "DEL"); push_reg(who_reg,r); default: break; } // next rsv-reg ++cur_rsv_n; } free(cur->reg), free(cur); free(next->reg), free(next); }