int OPTgroupsImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { int i, actions=0; InstrPtr q; InstrPtr *old, *ref; int limit,slimit; (void) cntxt; (void) stk; if (varGetProp(mb, getArg(mb->stmt[0], 0), inlineProp) != NULL) { return 0; } /* beware, new variables and instructions are introduced */ ref= (InstrPtr*) GDKzalloc(sizeof(InstrPtr) * mb->vtop); /* to find last assignment */ if ( ref == NULL) { return 0; } old= mb->stmt; limit= mb->stop; slimit= mb->ssize; if ( newMalBlkStmt(mb,mb->ssize) <0) { GDKfree(ref); return 0; } for (i = 0; i<limit; i++){ p= old[i]; if (getModuleId(p) == groupRef && p->argc == 4 && getFunctionId(p) == subgroupRef ){ setFunctionId(p, multicolumnsRef); ref[getArg(p,0)] = p; actions++; OPTDEBUGgroups { mnstr_printf(cntxt->fdout,"#new groups instruction\n"); printInstruction(cntxt->fdout,mb, 0, p, LIST_MAL_ALL); } } if (getModuleId(p) == groupRef && p->argc == 5 && getFunctionId(p) == subgroupdoneRef && ref[getArg(p,4)] != NULL){ /* * Try to expand its argument list with what we have found so far. * This creates a series of derive paths, many of which will be removed during deadcode elimination. */ q= copyInstruction(ref[getArg(p,4)]); q= pushArgument(mb, q, getArg(p,3)); getArg(q,0) = getArg(p,0); getArg(q,1) = getArg(p,1); getArg(q,2) = getArg(p,2); ref[getArg(q,0)] = q; freeInstruction(p); p= q; OPTDEBUGgroups{ mnstr_printf(cntxt->fdout,"#new groups instruction extension\n"); printInstruction(cntxt->fdout,mb, 0, p, LIST_MAL_ALL); } }
int OPTinlineImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { int i; InstrPtr q,sig; int actions = 0; (void) p; (void)stk; for (i = 1; i < mb->stop; i++) { q = getInstrPtr(mb, i); if( q->blk ) { sig = getInstrPtr(q->blk,0); /* * Time for inlining functions that are used in multiplex operations. * They are produced by SQL compiler. */ if( getFunctionId(q)== multiplexRef && getModuleId(q) == malRef && OPTinlineMultiplex(cntxt,mb,q)) { OPTDEBUGinline { mnstr_printf(cntxt->fdout,"#multiplex inline function\n"); printInstruction(cntxt->fdout,mb,0,q,LIST_MAL_ALL); } varSetProp(mb, getArg(q,0), inlineProp, op_eq, NULL); } else /* * Check if the function definition is tagged as being inlined. */ if (sig->token == FUNCTIONsymbol &&
void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info) { char *mnem; unsigned int i; x86_reg reg; // Try to print any aliases first. mnem = printAliasInstr(MI, OS, NULL); if (mnem) cs_mem_free(mnem); else printInstruction(MI, OS, NULL); if (MI->csh->detail) { // special instruction needs to supply register op reg = X86_insn_reg(MCInst_getOpcode(MI)); if (reg) { // add register operand for (i = 0;; i++) { // find the first empty slot to put it there if (MI->flat_insn->detail->x86.operands[i].type == 0) { MI->flat_insn->detail->x86.operands[i].type = X86_OP_REG; MI->flat_insn->detail->x86.operands[i].reg = reg; MI->flat_insn->detail->x86.op_count++; break; } } } } }
/**************new main function*****************/ int main(void) { int element,printChoice; NodePtr rootNodePtr=NULL; puts("enter a number to insert or enter a non-number to stop insert function\n"); printf("?:"); while(scanf("%d",&element)){ if(rootNodePtr==NULL){ rootNodePtr=(NodePtr)malloc(sizeof(Node)); rootNodePtr->number=element; rootNodePtr->leftPtr=NULL; rootNodePtr->rightPtr=NULL; } else{ insert(rootNodePtr,element); } printf("?:"); } getchar(); //第77行 scanf("%d",&i);是告诉电脑,你从输入流输入一个东西, printInstruction(); //如果他是整形(%d)判断,那么他将传递过来的地址 scanf("%d",&printChoice); //(&i是对i取地址)接收,否则将被继续放在缓存中。 //92行输入非数字就会进入死循环! 因为它一直被放在缓存中 while(printChoice!=4){ switch(printChoice){ case 1: inorderPrint(rootNodePtr); break; case 2: preorderPrint(rootNodePtr); break; case 3: postorderPrint(rootNodePtr); break; default: puts("invalid choice\n"); //printInstruction(); break; } fflush(stdin); // to clean the date in the cache printInstruction(); scanf("%d",&printChoice); } puts("function end\n"); return 0; } //end main function
void printAllInstructions(const INSTRUCTION *iHead) { const INSTRUCTION *i = iHead; while(i) { printInstruction(i); i = i->next; } }
void boardGame() { clearScreen(); printLogo(); pauseMessageAndClearScreen(NULL); printInstruction(); pauseMessageAndClearScreen(NULL); boardLoop(); }
void Mips_printInst(MCInst *MI, SStream *O, void *info) { switch (MCInst_getOpcode(MI)) { default: break; case Mips_RDHWR: case Mips_RDHWR64: SStream_concat(O, ".set\tpush\n"); SStream_concat(O, ".set\tmips32r2\n"); break; case Mips_Save16: SStream_concat(O, "\tsave\t"); printSaveRestore(MI, O); SStream_concat(O, " # 16 bit inst\n"); return; case Mips_SaveX16: SStream_concat(O, "\tsave\t"); printSaveRestore(MI, O); SStream_concat(O, "\n"); return; case Mips_Restore16: SStream_concat(O, "\trestore\t"); printSaveRestore(MI, O); SStream_concat(O, " # 16 bit inst\n"); return; case Mips_RestoreX16: SStream_concat(O, "\trestore\t"); printSaveRestore(MI, O); SStream_concat(O, "\n"); return; } // Try to print any aliases first. if (!printAliasInstr(MI, O, info) && !printAlias(MI, O)) printInstruction(MI, O, NULL); else { // fixup instruction id due to the change in alias instruction char *mnem = cs_strdup(O->buffer); char *tab = strchr(mnem, '\t'); if (tab) *tab = '\0'; // reflect the new insn name (alias) in the opcode unsigned id = Mips_map_insn(mnem); MCInst_setOpcode(MI, Mips_get_insn_id2(id)); MCInst_setOpcodePub(MI, id); cs_mem_free(mnem); } switch (MCInst_getOpcode(MI)) { default: break; case Mips_RDHWR: case Mips_RDHWR64: SStream_concat(O, "\n.set\tpop"); break; } }
void printCodeBlock(CodeBlock* codeBlock) { Instruction* pc = codeBlock->code; int i; for (i = 0 ; i < codeBlock->codeSize; i ++) { printf("%d: ",i); printInstruction(pc); printf("\n"); pc ++; } }
void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info) { char *mnem; x86_reg reg, reg2; enum cs_ac_type access1, access2; // Try to print any aliases first. mnem = printAliasInstr(MI, O, Info); if (mnem) cs_mem_free(mnem); else printInstruction(MI, O, Info); reg = X86_insn_reg_intel(MCInst_getOpcode(MI), &access1); if (MI->csh->detail) { #ifndef CAPSTONE_DIET uint8_t access[6]; #endif // first op can be embedded in the asm by llvm. // so we have to add the missing register as the first operand if (reg) { // shift all the ops right to leave 1st slot for this new register op memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]), sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1)); MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG; MI->flat_insn->detail->x86.operands[0].reg = reg; MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg]; MI->flat_insn->detail->x86.operands[0].access = access1; MI->flat_insn->detail->x86.op_count++; } else { if (X86_insn_reg_intel2(MCInst_getOpcode(MI), ®, &access1, ®2, &access2)) { MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG; MI->flat_insn->detail->x86.operands[0].reg = reg; MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg]; MI->flat_insn->detail->x86.operands[0].access = access1; MI->flat_insn->detail->x86.operands[1].type = X86_OP_REG; MI->flat_insn->detail->x86.operands[1].reg = reg2; MI->flat_insn->detail->x86.operands[1].size = MI->csh->regsize_map[reg2]; MI->flat_insn->detail->x86.operands[1].access = access2; MI->flat_insn->detail->x86.op_count = 2; } } #ifndef CAPSTONE_DIET get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags); MI->flat_insn->detail->x86.operands[0].access = access[0]; MI->flat_insn->detail->x86.operands[1].access = access[1]; #endif } if (MI->op1_size == 0 && reg) MI->op1_size = MI->csh->regsize_map[reg]; }
void printStackAndPc(int s[], int bp, int sp, int p[], int pc) { printf("[ "); int i; for (i=0; i<=sp; i++) if (IsInt(s[i])) printf("%d ", Untag(s[i])); else printf("#%d ", s[i]); printf("]"); printf("{%d:", pc); printInstruction(p, pc); printf("}\n"); }
/* *********************************************************************************************************** * generateASM: * filename : This has the filename of the file in which the ASM code will be written. * This function initiates the process of generation of code. This is called after * startGenertation which is actually responsible for creation three address code for all instructions * This function is responsible to print those three address code in meaningful way in the file specified. *********************************************************************************************************** */ void generateASM(char* filename){ InstructionList* head = CODE_HEAD; FILE* filePtr = fopen(filename,"w"); initializeCode(filePtr); while(head!=NULL){ printInstruction(filePtr,head); head = head->next; } finalizeCode(filePtr); fclose(filePtr); }
int main(int argc, char **argv) { genInstruction(instructionArray); printInstruction(); pageTable = (PageList)malloc(sizeof(PageNode)); pageTable->next = NULL; run(); return 0; }
void AVRInstPrinter::printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) { unsigned Opcode = MI->getOpcode(); // First handle load and store instructions with postinc or predec // of the form "ld reg, X+". // TODO: We should be able to rewrite this using TableGen data. switch (Opcode) { case AVR::LDRdPtr: case AVR::LDRdPtrPi: case AVR::LDRdPtrPd: O << "\tld\t"; printOperand(MI, 0, O); O << ", "; if (Opcode == AVR::LDRdPtrPd) O << '-'; printOperand(MI, 1, O); if (Opcode == AVR::LDRdPtrPi) O << '+'; break; case AVR::STPtrRr: O << "\tst\t"; printOperand(MI, 0, O); O << ", "; printOperand(MI, 1, O); break; case AVR::STPtrPiRr: case AVR::STPtrPdRr: O << "\tst\t"; if (Opcode == AVR::STPtrPdRr) O << '-'; printOperand(MI, 1, O); if (Opcode == AVR::STPtrPiRr) O << '+'; O << ", "; printOperand(MI, 2, O); break; default: if (!printAliasInstr(MI, O)) printInstruction(MI, O); printAnnotation(O, Annot); break; } }
/* Fetch and execute */ void run() { while (doRun) { /* Fetch Instruction*/ word w = loadWord(pc); Instruction *instruction = (Instruction *) &w; pc += 4; /* Execute Instruction*/ operations[instruction->i.opcode].operation(instruction); /* In case you want to watch the machine */ if (verbose) { printInstruction(instruction); } } }
int step(void) { Instruction inst = program->instructions[pc]; int error = handlers[inst.op](&inst); if (error < 0) { return error; } if (pc >= program->size) { return PC_ERROR; } fprintf(stderr, "pc @ 0x%X\t", pc); printInstruction(&program->instructions[pc]); fprintf(stderr, "\n"); return 0; }
int traceReg(ThreadState *state, int start, int regIdx) { auto tracer = state->tracer; auto tracerSize = static_cast<int>(tracer->trace.size()); debugPrint("Trace - Search {} to {} for write r{}", start, tracerSize, regIdx); assert(start >= 0); assert(start < tracerSize); for (auto i = start; i < tracerSize; ++i) { auto &trace = getTrace(tracer, i); bool wasMatchedWrite = false; for (auto j = 0u; j < trace.data->write.size(); ++j) { int writeReg = getFieldReg(trace.instr, trace.data->write[j]); if (writeReg == regIdx) { wasMatchedWrite = true; } } if (trace.data->id == InstructionID::kc) { debugPrint(" Possible Match via KC"); printInstruction(trace, i); } if (wasMatchedWrite) { printInstruction(trace, i); return i; } } debugPrint(" Nothing Found"); return -1; }
/* * find all the leaders (instruction) in the InstrList given, * leaders returned as an ArrayList(set) of Instruction* */ ArrayList *findLeaders(InstrList *iList){ Instruction *temp_ins; ArrayList *leaders = al_newGeneric(AL_LIST_SET, addressCompare, refPrint, NULL); int i=0; //add first instr into leader list Instruction *instr = getInstruction(iList, i); al_add(leaders, (void *)(instr->addr)); for(i=0;i<iList->numInstrs;i++){ Instruction *instr = getInstruction(iList, i); //ignore non-jump instructions and native invocations if(!isBranch(iList, instr) && !isRetInstruction(iList, instr) && !(isInvokeInstruction(iList, instr) && INSTR_HAS_FLAG(instr, INSTR_IS_SCRIPT_INVOKE)) ) continue; /* add: * instr as target of jump * instr immediately after jump */ if(isBranch(iList, instr)){ if(!instr->jmpOffset){ printInstruction(instr); } assert(instr->jmpOffset); al_add(leaders, (void *)(instr->addr + instr->jmpOffset)); assert(instr->length>0); al_add(leaders, (void *)(instr->addr + instr->length)); } else if(isRetInstruction(iList, instr)){ if(i < iList->numInstrs-1){ temp_ins = getInstruction(iList, i+1); al_add(leaders, (void *)(temp_ins->addr)); } } else{ //non-native invoke and document.write() which generate code if(i < iList->numInstrs-1){ assert(isInvokeInstruction(iList, instr) && INSTR_HAS_FLAG(instr, INSTR_IS_SCRIPT_INVOKE)); temp_ins = getInstruction(iList, i+1); al_add(leaders, (void *)(temp_ins->addr)); } } } return leaders; }
/* -------------------------------------------------------------------------------------- */ void dumpBasicBlock(BasicBlock *p){ int i; ins *tmp; if(p == NULL){ return; } i = 0; tmp = p->head; while (tmp != NULL){ printInstruction(tmp); // printf("\n"); tmp = tmp->next; i++; } }
/** * Print the given basic block. * * @param block the basic block */ void JVMWriter::printBasicBlock(const BasicBlock *block) { printLabel(getLabelName(block)); if (trace) { if (block->hasName()) { std::string n = block->getName(); printTrc(n + ":"); } } for(BasicBlock::const_iterator i = block->begin(), e = block->end(); i != e; i++) { instNum++; if (trace) printSimpleInstruction(".line", utostr(trcLineNum+1)); else if(debug >= 1) printSimpleInstruction(".line", utostr(instNum)); if(debug >= 3 || trace) { // print current instruction as comment // note that this block of code significantly increases // code generation time std::string str; raw_string_ostream ss(str); ss << *i; ss.flush(); if (trace) printTrc(str); if (debug >= 3) { std::string::size_type pos = 0; while((pos = str.find("\n", pos)) != std::string::npos) str.replace(pos++, 1, "\n;"); out << ';' << str << '\n'; } } if(i->getOpcode() == Instruction::PHI) // don't handle phi instruction in current block continue; printInstruction(i); if(i->getType() != Type::getVoidTy(block->getContext()) && i->getOpcode() != Instruction::Invoke) // instruction doesn't return anything, or is an invoke instruction // which handles storing the return value itself printValueStore(i); } }
/* -------------------------------------------------------------------------------------- */ void printBasicBlock(BasicBlock *p){ int i; ins *tmp; if(p == NULL){ printf("(nil)"); return; } printf(" Basic Block: %d\n",p->idx); i = 0; tmp = p->head; while (tmp != NULL){ printf("%d: ",i); printInstruction(tmp); // printf("\n"); tmp = tmp->next; i++; } }
void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info) { //if (TSFlags & X86II::LOCK) // O << "\tlock\n"; if (printAliasInstr(MI, O)) { char *mnem = cs_strdup(O->buffer); char *tab = strchr(mnem, '\t'); if (tab) *tab = '\0'; // reflect the new insn name (alias) in the opcode MCInst_setOpcode(MI, X86_get_insn_id2(X86_map_insn(mnem))); cs_mem_free(mnem); } else printInstruction(MI, O, NULL); if (MI->csh->detail) { char tmp[64]; if (get_first_op(O->buffer, tmp)) { int post; char *acc_regs[] = { "al", "ax", "eax", "rax", NULL }; unsigned int acc_regs_id[] = { X86_REG_AL, X86_REG_AX, X86_REG_EAX, X86_REG_RAX }; if (tmp[0] != 0 && ((post = str_in_list(acc_regs, tmp)) != -1)) { // first op is register, so set operand size following register size MI->flat_insn.x86.op_size = 1 << post; // tmp is a register if ((MI->flat_insn.x86.operands[0].type != X86_OP_INVALID) && ((MI->flat_insn.x86.operands[0].type != X86_OP_REG) || (MI->flat_insn.x86.operands[0].reg != acc_regs_id[post]))) { // first op is register, so insert its detail to position 0 int i; for (i = MI->flat_insn.x86.op_count; i > 0; i--) { memcpy(&(MI->flat_insn.x86.operands[i]), &(MI->flat_insn.x86.operands[i - 1]), sizeof(MI->flat_insn.x86.operands[0])); } MI->flat_insn.x86.operands[0].type = X86_OP_REG; MI->flat_insn.x86.operands[0].reg = x86_map_regname(tmp); MI->flat_insn.x86.op_count++; } } } } }
void tracePrint(ThreadState *state, int start, int count) { auto tracer = state->tracer; auto tracerSize = static_cast<int>(tracer->trace.size()); if (count == 0) { count = tracerSize - start; } int end = start + count; assert(start >= 0); assert(end <= tracerSize); debugPrint("Trace - Print {} to {}", start, end); for (auto i = start; i < end; ++i) { auto &trace = getTrace(tracer, i); printInstruction(trace, i); } }
void XCore_printInst(MCInst *MI, SStream *O, void *Info) { printInstruction(MI, O, Info); }
/* * The generic solution to the multiplex operators is to translate * them to a MAL loop. * The call optimizer.multiplex(MOD,FCN,A1,...An) introduces the following code * structure: * * @verbatim * A1rev:=bat.reverse(A1); * resB:= bat.new(A1); * barrier (h,t):= iterator.new(A1); * $1:= algebra.fetch(A1,h); * $2:= A2; # in case of constant? * ... * cr:= MOD.FCN($1,...,$n); * y:=algebra.fetch(A1rev,h); * bat.insert(resB,y,cr); * redo (h,t):= iterator.next(A1); * end h; * @end verbatim * * The algorithm consists of two phases: phase one deals with * collecting the relevant information, phase two is the actual * code construction. */ static str OPTexpandMultiplex(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i = 2, resB, iter = 0, cr; int hvar, tvar; int x, y; str mod, fcn; int *alias; InstrPtr q; int ht, tt; (void) cntxt; (void) stk; ht = getHeadType(getArgType(mb, pci, 0)); if (ht != TYPE_oid) throw(MAL, "optimizer.multiplex", "Target head type is missing"); tt = getTailType(getArgType(mb, pci, 0)); if (tt== TYPE_any) throw(MAL, "optimizer.multiplex", "Target tail type is missing"); if (isAnyExpression(getArgType(mb, pci, 0))) throw(MAL, "optimizer.multiplex", "Target type is missing"); mod = VALget(&getVar(mb, getArg(pci, 1))->value); mod = putName(mod,strlen(mod)); fcn = VALget(&getVar(mb, getArg(pci, 2))->value); fcn = putName(fcn,strlen(fcn)); /* search the iterator bat */ for (i = 3; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { iter = getArg(pci, i); if (getHeadType(getVarType(mb,iter)) != TYPE_oid) throw(MAL, "optimizer.multiplex", "Iterator BAT is not OID-headed"); break; } if( i == pci->argc) throw(MAL, "optimizer.multiplex", "Iterator BAT type is missing"); OPTDEBUGmultiplex { mnstr_printf(cntxt->fdout,"#calling the optimize multiplex script routine\n"); printFunction(cntxt->fdout,mb, 0, LIST_MAL_ALL ); mnstr_printf(cntxt->fdout,"#multiplex against operator %d %s\n",iter, getTypeName(getVarType(mb,iter))); printInstruction(cntxt->fdout,mb, 0, pci,LIST_MAL_ALL); } /* * Beware, the operator constant (arg=1) is passed along as well, * because in the end we issue a recursive function call that should * find the actual arguments at the proper place of the callee. */ alias= (int*) GDKmalloc(sizeof(int) * pci->maxarg); if (alias == NULL) return NULL; /* x := bat.reverse(A1); */ x = newTmpVariable(mb, newBatType(getTailType(getVarType(mb,iter)), getHeadType(getVarType(mb,iter)))); q = newFcnCall(mb, batRef, reverseRef); getArg(q, 0) = x; q = pushArgument(mb, q, iter); /* resB := new(refBat) */ q = newFcnCall(mb, batRef, newRef); resB = getArg(q, 0); setVarType(mb, getArg(q, 0), newBatType(ht, tt)); q = pushType(mb, q, ht); q = pushType(mb, q, tt); /* barrier (h,r) := iterator.new(refBat); */ q = newFcnCall(mb, iteratorRef, newRef); q->barrier = BARRIERsymbol; hvar = newTmpVariable(mb, TYPE_any); getArg(q,0) = hvar; tvar = newTmpVariable(mb, TYPE_any); q= pushReturn(mb, q, tvar); (void) pushArgument(mb,q,iter); /* $1:= algebra.fetch(Ai,h) or constant */ alias[i] = tvar; for (i++; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { q = newFcnCall(mb, algebraRef, "fetch"); alias[i] = newTmpVariable(mb, getTailType(getArgType(mb, pci, i))); getArg(q, 0) = alias[i]; q= pushArgument(mb, q, getArg(pci, i)); (void) pushArgument(mb, q, hvar); } /* cr:= mod.CMD($1,...,$n); */ q = newFcnCall(mb, mod, fcn); cr = getArg(q, 0) = newTmpVariable(mb, TYPE_any); for (i = 3; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { q= pushArgument(mb, q, alias[i]); } else { q = pushArgument(mb, q, getArg(pci, i)); } /* y := algebra.fetch(x,h); */ y = newTmpVariable(mb, getHeadType(getVarType(mb,iter))); q = newFcnCall(mb, algebraRef, "fetch"); getArg(q, 0) = y; q = pushArgument(mb, q, x); q = pushArgument(mb, q, hvar); /* insert(resB,h,cr); not append(resB, cr); the head type (oid) may dynamically change */ q = newFcnCall(mb, batRef, insertRef); q= pushArgument(mb, q, resB); q= pushArgument(mb, q, y); (void) pushArgument(mb, q, cr); /* redo (h,r):= iterator.next(refBat); */ q = newFcnCall(mb, iteratorRef, nextRef); q->barrier = REDOsymbol; getArg(q,0) = hvar; q= pushReturn(mb, q, tvar); (void) pushArgument(mb,q,iter); q = newAssignment(mb); q->barrier = EXITsymbol; getArg(q,0) = hvar; (void) pushReturn(mb, q, tvar); q = newAssignment(mb); getArg(q, 0) = getArg(pci, 0); (void) pushArgument(mb, q, resB); GDKfree(alias); return MAL_SUCCEED; }
void Sparc_printInst(MCInst *MI, SStream *O, void *Info) { char *mnem, *p; char instr[64]; // Sparc has no instruction this long mnem = printAliasInstr(MI, O, Info); if (mnem) { // fixup instruction id due to the change in alias instruction strncpy(instr, mnem, strlen(mnem)); instr[strlen(mnem)] = '\0'; // does this contains hint with a coma? p = strchr(instr, ','); if (p) *p = '\0'; // now instr only has instruction mnemonic MCInst_setOpcodePub(MI, Sparc_map_insn(instr)); switch(MCInst_getOpcode(MI)) { case SP_BCOND: case SP_BCONDA: case SP_BPICCANT: case SP_BPICCNT: case SP_BPXCCANT: case SP_BPXCCNT: case SP_TXCCri: case SP_TXCCrr: if (MI->csh->detail) { // skip 'b', 't' MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 1); MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); } break; case SP_BPFCCANT: case SP_BPFCCNT: if (MI->csh->detail) { // skip 'fb' MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 2); MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); } break; case SP_FMOVD_ICC: case SP_FMOVD_XCC: case SP_FMOVQ_ICC: case SP_FMOVQ_XCC: case SP_FMOVS_ICC: case SP_FMOVS_XCC: if (MI->csh->detail) { // skip 'fmovd', 'fmovq', 'fmovs' MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 5); MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); } break; case SP_MOVICCri: case SP_MOVICCrr: case SP_MOVXCCri: case SP_MOVXCCrr: if (MI->csh->detail) { // skip 'mov' MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 3); MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); } break; case SP_V9FMOVD_FCC: case SP_V9FMOVQ_FCC: case SP_V9FMOVS_FCC: if (MI->csh->detail) { // skip 'fmovd', 'fmovq', 'fmovs' MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 5); MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); } break; case SP_V9MOVFCCri: case SP_V9MOVFCCrr: if (MI->csh->detail) { // skip 'mov' MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 3); MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); } break; default: break; } cs_mem_free(mnem); } else { if (!printSparcAliasInstr(MI, O)) printInstruction(MI, O, NULL); } }
void SystemZ_printInst(MCInst *MI, SStream *O, void *Info) { printInstruction(MI, O, Info); }
void AArch64_printInst(MCInst *MI, SStream *O, void *Info) { // Check for special encodings and print the canonical alias instead. unsigned Opcode = MCInst_getOpcode(MI); int LSB; int Width; char *mnem; if (Opcode == AArch64_SYSxt && printSysAlias(MI, O)) return; // SBFM/UBFM should print to a nicer aliased form if possible. if (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri || Opcode == AArch64_UBFMXri || Opcode == AArch64_UBFMWri) { MCOperand *Op0 = MCInst_getOperand(MI, 0); MCOperand *Op1 = MCInst_getOperand(MI, 1); MCOperand *Op2 = MCInst_getOperand(MI, 2); MCOperand *Op3 = MCInst_getOperand(MI, 3); bool IsSigned = (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri); bool Is64Bit = (Opcode == AArch64_SBFMXri || Opcode == AArch64_UBFMXri); if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) == 0 && MCOperand_isImm(Op3)) { char *AsmMnemonic = NULL; switch (MCOperand_getImm(Op3)) { default: break; case 7: if (IsSigned) AsmMnemonic = "sxtb"; else if (!Is64Bit) AsmMnemonic = "uxtb"; break; case 15: if (IsSigned) AsmMnemonic = "sxth"; else if (!Is64Bit) AsmMnemonic = "uxth"; break; case 31: // *xtw is only valid for signed 64-bit operations. if (Is64Bit && IsSigned) AsmMnemonic = "sxtw"; break; } if (AsmMnemonic) { SStream_concat(O, "%s\t%s, %s", AsmMnemonic, getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName), getRegisterName(getWRegFromXReg(MCOperand_getReg(Op1)), AArch64_NoRegAltName)); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = getWRegFromXReg(MCOperand_getReg(Op1)); MI->flat_insn->detail->arm64.op_count++; } MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic)); return; } } // All immediate shifts are aliases, implemented using the Bitfield // instruction. In all cases the immediate shift amount shift must be in // the range 0 to (reg.size -1). if (MCOperand_isImm(Op2) && MCOperand_isImm(Op3)) { char *AsmMnemonic = NULL; int shift = 0; int immr = (int)MCOperand_getImm(Op2); int imms = (int)MCOperand_getImm(Op3); if (Opcode == AArch64_UBFMWri && imms != 0x1F && ((imms + 1) == immr)) { AsmMnemonic = "lsl"; shift = 31 - imms; } else if (Opcode == AArch64_UBFMXri && imms != 0x3f && ((imms + 1 == immr))) { AsmMnemonic = "lsl"; shift = 63 - imms; } else if (Opcode == AArch64_UBFMWri && imms == 0x1f) { AsmMnemonic = "lsr"; shift = immr; } else if (Opcode == AArch64_UBFMXri && imms == 0x3f) { AsmMnemonic = "lsr"; shift = immr; } else if (Opcode == AArch64_SBFMWri && imms == 0x1f) { AsmMnemonic = "asr"; shift = immr; } else if (Opcode == AArch64_SBFMXri && imms == 0x3f) { AsmMnemonic = "asr"; shift = immr; } if (AsmMnemonic) { SStream_concat(O, "%s\t%s, %s, ", AsmMnemonic, getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName), getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName)); printInt32Bang(O, shift); MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic)); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = shift; MI->flat_insn->detail->arm64.op_count++; } return; } } // SBFIZ/UBFIZ aliases if (MCOperand_getImm(Op2) > MCOperand_getImm(Op3)) { SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfiz" : "ubfiz"), getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName), getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName)); printInt32Bang(O, (int)((Is64Bit ? 64 : 32) - MCOperand_getImm(Op2))); SStream_concat0(O, ", "); printInt32Bang(O, (int)MCOperand_getImm(Op3) + 1); MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfiz" : "ubfiz")); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (Is64Bit ? 64 : 32) - (int)MCOperand_getImm(Op2); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)MCOperand_getImm(Op3) + 1; MI->flat_insn->detail->arm64.op_count++; } return; } // Otherwise SBFX/UBFX is the preferred form SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfx" : "ubfx"), getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName), getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName)); printInt32Bang(O, (int)MCOperand_getImm(Op2)); SStream_concat0(O, ", "); printInt32Bang(O, (int)MCOperand_getImm(Op3) - (int)MCOperand_getImm(Op2) + 1); MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfx" : "ubfx")); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)MCOperand_getImm(Op2); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)MCOperand_getImm(Op3) - (int)MCOperand_getImm(Op2) + 1; MI->flat_insn->detail->arm64.op_count++; } return; } if (Opcode == AArch64_BFMXri || Opcode == AArch64_BFMWri) { MCOperand *Op0 = MCInst_getOperand(MI, 0); // Op1 == Op0 MCOperand *Op2 = MCInst_getOperand(MI, 2); int ImmR = (int)MCOperand_getImm(MCInst_getOperand(MI, 3)); int ImmS = (int)MCOperand_getImm(MCInst_getOperand(MI, 4)); // BFI alias if (ImmS < ImmR) { int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32; LSB = (BitWidth - ImmR) % BitWidth; Width = ImmS + 1; SStream_concat(O, "bfi\t%s, %s, ", getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName), getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName)); printInt32Bang(O, LSB); SStream_concat0(O, ", "); printInt32Bang(O, Width); MCInst_setOpcodePub(MI, AArch64_map_insn("bfi")); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB; MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width; MI->flat_insn->detail->arm64.op_count++; } return; } LSB = ImmR; Width = ImmS - ImmR + 1; // Otherwise BFXIL the preferred form SStream_concat(O, "bfxil\t%s, %s, ", getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName), getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName)); printInt32Bang(O, LSB); SStream_concat0(O, ", "); printInt32Bang(O, Width); MCInst_setOpcodePub(MI, AArch64_map_insn("bfxil")); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2); MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB; MI->flat_insn->detail->arm64.op_count++; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width; MI->flat_insn->detail->arm64.op_count++; } return; } mnem = printAliasInstr(MI, O, Info); if (mnem) { MCInst_setOpcodePub(MI, AArch64_map_insn(mnem)); cs_mem_free(mnem); } else { printInstruction(MI, O, Info); } }
int OPTevaluateImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { InstrPtr p; int i, k, limit, *alias, barrier; MalStkPtr env = NULL; int profiler; str msg; int debugstate = cntxt->itrace, actions = 0, constantblock = 0; int *assigned, setonce; cntxt->itrace = 0; (void)stk; (void)pci; if (varGetProp(mb, getArg(mb->stmt[0], 0), inlineProp) != NULL) return 0; (void)cntxt; OPTDEBUGevaluate mnstr_printf(cntxt->fdout, "Constant expression optimizer started\n"); assigned = (int*) GDKzalloc(sizeof(int) * mb->vtop); if (assigned == NULL) return 0; alias = (int*)GDKzalloc(mb->vsize * sizeof(int) * 2); /* we introduce more */ if (alias == NULL){ GDKfree(assigned); return 0; } // arguments are implicitly assigned by context p = getInstrPtr(mb, 0); for ( k =p->retc; k < p->argc; k++) assigned[getArg(p,k)]++; limit = mb->stop; for (i = 1; i < limit; i++) { p = getInstrPtr(mb, i); // The double count emerging from a barrier exit is ignored. if (! blockExit(p) || (blockExit(p) && p->retc != p->argc)) for ( k =0; k < p->retc; k++) assigned[getArg(p,k)]++; } for (i = 1; i < limit; i++) { p = getInstrPtr(mb, i); for (k = p->retc; k < p->argc; k++) if (alias[getArg(p, k)]) getArg(p, k) = alias[getArg(p, k)]; // to avoid management of duplicate assignments over multiple blocks // we limit ourselfs to evaluation of the first assignment only. setonce = assigned[getArg(p,0)] == 1; OPTDEBUGevaluate printInstruction(cntxt->fdout, mb, 0, p, LIST_MAL_ALL); constantblock += blockStart(p) && OPTallConstant(cntxt,mb,p); /* be aware that you only assign once to a variable */ if (setonce && p->retc == 1 && OPTallConstant(cntxt, mb, p) && !isUnsafeFunction(p)) { barrier = p->barrier; p->barrier = 0; profiler = malProfileMode; /* we don't trace it */ malProfileMode = 0; if ( env == NULL) { env = prepareMALstack(mb, 2 * mb->vsize ); env->keepAlive = TRUE; } msg = reenterMAL(cntxt, mb, i, i + 1, env); malProfileMode= profiler; p->barrier = barrier; OPTDEBUGevaluate { mnstr_printf(cntxt->fdout, "#retc var %s\n", getVarName(mb, getArg(p, 0))); mnstr_printf(cntxt->fdout, "#result:%s\n", msg == MAL_SUCCEED ? "ok" : msg); } if (msg == MAL_SUCCEED) { int nvar; ValRecord cst; actions++; cst.vtype = 0; VALcopy(&cst, &env->stk[getArg(p, 0)]); /* You may not overwrite constants. They may be used by * other instructions */ nvar = getArg(p, 1) = defConstant(mb, getArgType(mb, p, 0), &cst); if (nvar >= env->stktop) { VALcopy(&env->stk[getArg(p, 1)], &getVarConstant(mb, getArg(p, 1))); env->stktop = getArg(p, 1) + 1; } alias[getArg(p, 0)] = getArg(p, 1); p->argc = 2; p->token = ASSIGNsymbol; clrFunction(p); p->barrier = barrier; /* freeze the type */ setVarFixed(mb,getArg(p,1)); setVarUDFtype(mb,getArg(p,1)); OPTDEBUGevaluate { mnstr_printf(cntxt->fdout, "Evaluated new constant=%d -> %d:%s\n", getArg(p, 0), getArg(p, 1), getTypeName(getArgType(mb, p, 1))); } } else {
void printSetEnded() { printInstruction(2+32+128); }
void printSetStarted() { printInstruction(2+4+8+16+64+128); }