void parse_asmdirective(char *dir, char *str, int integer, float fnum) { if (strcmp(dir, ".text") == 0) // deprecated { Warning("Deprecated assembler directive %s", dir); } else if (strcmp(dir, ".data") == 0) // deprecated { Warning("Deprecated assembler directive %s", dir); } else if (strcmp(dir, ".byte") == 0) { if (str) { Error("Unsupported data type for label"); } emit8(integer); } else if (strcmp(dir, ".word") == 0) { if (str) { Error("Unsupported data type for label"); } emit16(integer); } else if (strcmp(dir, ".dword") == 0) { if (str) { AddRelocEntry(str, codeptr); emit32(0); } else { emit32(integer); } } else if (strcmp(dir, ".float") == 0) { if (str) { Error("Unsupported data type for label"); } emitfloat(fnum); } else if (strcmp(dir, ".string") == 0) { assert(str != 0); output_string(str); } }
void encode_sub_sp(struct buffer *buffer, unsigned long frame_size) { /* * The max immediate value which can be added or subtracted from * a register is 255 so to make large frame we have to emit * subtract insn more than one time. */ while (frame_size > MAX_FRAME_SIZE_SUBTRACTED) { emit32(buffer, ARM_SUB_IMM8(ARM_SP, ARM_SP, MAX_FRAME_SIZE_SUBTRACTED)); frame_size = frame_size - MAX_FRAME_SIZE_SUBTRACTED; } if (frame_size > 0) emit32(buffer, ARM_SUB_IMM8(ARM_SP, ARM_SP, frame_size)); }
void encode_ldm(struct buffer *buffer, uint16_t register_list) { uint32_t encoded_insn; encoded_insn = AL | MULTIPLE_LOAD_STORE | LOAD_INSN | DECREMENT_BEFORE | ((arm_encode_reg(MACH_REG_SP) & 0xF) << 16) | register_list; emit32(buffer, encoded_insn); }
void output_insb1label(char *instruction, char *label) { OpcodeEntry *opc = LookupOpcodeByString(instruction); emit8(opc->OpCode); AddRelocEntry(label, codeptr); emit32(0); }
void shil_stream::mov(Sh4RegType to,u32 from) { if (IsReg64(to)) { log("SHIL ERROR\n"); } emit32(shilop_mov,to,from); //emit(shilop_mov,to,from); }
void output_ins2const(char *instruction, char *ra, int constant) { OpcodeEntry *opc = LookupOpcodeByString(instruction); RegisterEntry *rega = LookupRegisterByName(ra); emit8(opc->OpCode); emit8(rega->Register); emit32(constant); }
void Assembler::align() { long data; g_nops = getCpu()->getOp()->get(); data = ((Operands6502 *)getCpu()->getOp())->op[0].val.value; DoingDc = true; gSzChar = 'B'; switch(CurrentArea) { case CODE_AREA: //while(ProgramCounter.byte) // emit8(0xff); if (ProgramCounter.val % data) { while(ProgramCounter.val % data) emit8(0xff); } break; case DATA_AREA: while(DataCounter.byte) emit8(0xff); if (DataCounter.val % data) { while(DataCounter.val % data) emit32(0xffffffff); } break; case BSS_AREA: // while(BSSCounter.byte) // emit8(0xff); if (BSSCounter.val % data) { while(BSSCounter.val % data) { emit32(0xffffffff); } } break; } DoingDc = false; }
void output_ins2label(char *instruction, char *ra, char *label) { OpcodeEntry *opc = LookupOpcodeByString(instruction); RegisterEntry *rega = LookupRegisterByName(ra); emit8(opc->OpCode); emit8(rega->Register); AddRelocEntry(label, codeptr); emit32(0); }
void encode_store_args(struct buffer *buffer, struct stack_frame *frame) { unsigned long nr_args_to_save; unsigned long i; long offset = 0; uint32_t encoded_insn; if (frame->nr_args > 4) nr_args_to_save = 4; else nr_args_to_save = frame->nr_args; for (i = 0; i < nr_args_to_save; i++) { offset = arg_offset(frame, i); offset = offset * (-1); encoded_insn = arm_encode_table[INSN_STR_MEMLOCAL_REG]; encoded_insn = encoded_insn | IMM_OFFSET_SUB | ((arm_encode_reg(MACH_REG_FP) & 0xF) << 16) | ((arm_encode_reg(arg_regs[i]) & 0xFF) << 12) | (offset & 0xFFF); emit32(buffer, encoded_insn); } }
/* * We have to pass the address of cu so that we can call magic_trampoline * But addr of cu is of 32 bit and we can use only 8-bit imm so * we need to have addr of cu in our constant pool which will be emitted * at the starting. */ void encode_setup_trampoline(struct buffer *buffer, uint32_t cu_addr, uint32_t target_addr) { uint32_t encoded_insn; /* * Branch to the call instruction directly. This branch is added * because just after this insn addresses of cu and * jit_magic_trampoline are emitted which are not instructions. */ emit32(buffer, ARM_B(ARM_BRANCH_OFFSET(0x04))); /* Emit the address of cu */ emit32(buffer, cu_addr); /* Emit the address of magic_tampoline */ emit32(buffer, target_addr); /* Load the addr of cu in R0 */ encoded_insn = arm_encode_table[INSN_LDR_REG_MEMLOCAL]; encoded_insn = encoded_insn | IMM_OFFSET_SUB | ((arm_encode_reg(MACH_REG_R0) & 0xF) << 12) | ((arm_encode_reg(MACH_REG_PC) & 0xF) << 16) | (0x010); emit32(buffer, encoded_insn); /* * Call jit_magic_trampoline. First store the value of PC in LR and * then load the address of magic_trampoline form constant pool. */ emit32(buffer, ARM_SUB_IMM8(ARM_LR, ARM_PC, 0)); encoded_insn = arm_encode_table[INSN_LDR_REG_MEMLOCAL]; encoded_insn = encoded_insn | IMM_OFFSET_SUB | ((arm_encode_reg(MACH_REG_PC) & 0xF) << 12) | ((arm_encode_reg(MACH_REG_PC) & 0xF) << 16) | (0x014); emit32(buffer, encoded_insn); }
void shil_stream::sar(Sh4RegType to,u8 count) { emit32(shilop_sar,to,count); }
void shil_stream::fcmp(Sh4RegType to,Sh4RegType from) { emit32(shilop_fcmp,to,from,FLAG_SETFLAGS); }
void shil_stream::sub(Sh4RegType to,u32 from) { emit32(shilop_sub,to,from); }
void shil_stream::add(Sh4RegType to,u32 from) { emit32(shilop_add,to,from); }
//maths (integer) void shil_stream::adc(Sh4RegType to,Sh4RegType from) { emit32(shilop_adc,to,from); }
void shil_stream::SaveT(cmd_cond cond) { emit32(shilop_SaveT,(u32)cond); }
int Assembler::out32(Opa *o) { emit32(o->oc); return (TRUE); }
void shil_stream::xor(Sh4RegType to,u32 from) { emit32(shilop_xor,to,from); }
void shil_stream::cmp(Sh4RegType to,s8 from) { emit32(shilop_cmp,to,from); }
void shil_stream::or(Sh4RegType to,Sh4RegType from) { emit32(shilop_or,to,from); }
//bitwise ops void shil_stream::and(Sh4RegType to,Sh4RegType from) { emit32(shilop_and,to,from); }
void shil_stream::not(Sh4RegType to) { emit32(shilop_not,to); }
void shil_stream::neg(Sh4RegType to) { emit32(shilop_neg,to); }
void shil_stream::LoadT(x86_flags to) { emit32(shilop_LoadT,(u32)to); }
//******* opcode emitters ****** void shil_stream::jcond(u32 cond) { emit32(shilop_jcond,cond); }
void shil_stream::rcl(Sh4RegType to) { emit32(shilop_rcl,to); }
// Emit 3 bytes, one short operand int emit3(u1 opcode, u2 operand) { return emit32(opcode, HI(operand), LO(operand)); }
void shil_stream::ror(Sh4RegType to) { emit32(shilop_ror,to); }
//logical shifts void shil_stream::shl(Sh4RegType to,u8 count) { emit32(shilop_shl,to,count); }
void shil_stream::test(Sh4RegType to,u8 from) { emit32(shilop_test,to,from); }