diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-06-21 22:50:33 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-06-21 22:50:33 -0700 |
commit | 5c2a362cb79d9aaf5fc69cf05a56d67d98f8b737 (patch) | |
tree | 085101581ed71b5b3d96ce3887efdbff084e1e35 /src/arch/arm/insts | |
parent | d4a03f19009b9a537d99d54620784d441f9c3a92 (diff) | |
download | gem5-5c2a362cb79d9aaf5fc69cf05a56d67d98f8b737.tar.xz |
ARM: Move util functions out of the isa desc.
Diffstat (limited to 'src/arch/arm/insts')
-rw-r--r-- | src/arch/arm/insts/static_inst.cc | 228 | ||||
-rw-r--r-- | src/arch/arm/insts/static_inst.hh | 59 |
2 files changed, 271 insertions, 16 deletions
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index ae53199fa..64bc9751f 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -31,7 +31,228 @@ namespace ArmISA { -void ArmStaticInst::printReg(std::ostream &os, int reg) const +static int32_t arm_NEG(int32_t val) { return (val >> 31); } +static int32_t arm_POS(int32_t val) { return ((~val) >> 31); } + +// Shift Rm by an immediate value +int32_t +ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, + uint32_t type, uint32_t cfval) const +{ + enum ArmShiftType shiftType; + shiftType = (enum ArmShiftType) type; + + switch (shiftType) + { + case LSL: + return (base << shamt); + case LSR: + if (shamt == 0) + return (0); + else + return (base >> shamt); + case ASR: + if (shamt == 0) + return ((uint32_t) ((int32_t) base >> 31L)); + else + return ((uint32_t) (((int32_t) base) >> shamt)); + case ROR: + //shamt = shamt & 0x1f; + if (shamt == 0) + return (cfval << 31) | (base >> 1); // RRX + else + return (base << (32 - shamt)) | (base >> shamt); + default: + fprintf(stderr, "Unhandled shift type\n"); + exit(1); + break; + } + return 0; +} + +// Shift Rm by Rs +int32_t +ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, + uint32_t type, uint32_t cfval) const +{ + enum ArmShiftType shiftType; + shiftType = (enum ArmShiftType) type; + + switch (shiftType) + { + case LSL: + if (shamt == 0) + return (base); + else if (shamt >= 32) + return (0); + else + return (base << shamt); + case LSR: + if (shamt == 0) + return (base); + else if (shamt >= 32) + return (0); + else + return (base >> shamt); + case ASR: + if (shamt == 0) + return base; + else if (shamt >= 32) + return ((uint32_t) ((int32_t) base >> 31L)); + else + return ((uint32_t) (((int32_t) base) >> (int) shamt)); + case ROR: + shamt = shamt & 0x1f; + if (shamt == 0) + return (base); + else + return ((base << (32 - shamt)) | (base >> shamt)); + default: + fprintf(stderr, "Unhandled shift type\n"); + exit(1); + break; + } + return 0; +} + + +// Generate C for a shift by immediate +int32_t +ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, + uint32_t type, uint32_t cfval) const +{ + enum ArmShiftType shiftType; + shiftType = (enum ArmShiftType) type; + + switch (shiftType) + { + case LSL: + return (base >> (32 - shamt)) & 1; + case LSR: + if (shamt == 0) + return (base >> 31) & 1; + else + return (base >> (shamt - 1)) & 1; + case ASR: + if (shamt == 0) + return (base >> 31L); + else + return ((uint32_t) (((int32_t) base) >> (shamt - 1))) & 1; + case ROR: + shamt = shamt & 0x1f; + if (shamt == 0) + return (base & 1); // RRX + else + return (base >> (shamt - 1)) & 1; + default: + fprintf(stderr, "Unhandled shift type\n"); + exit(1); + break; + + } + return 0; +} + + +// Generate C for a shift by Rs +int32_t +ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, + uint32_t type, uint32_t cfval) const +{ + enum ArmShiftType shiftType; + shiftType = (enum ArmShiftType) type; + + switch (shiftType) + { + case LSL: + if (shamt == 0) + return (!!cfval); + else if (shamt == 32) + return (base & 1); + else if (shamt > 32) + return (0); + else + return ((base >> (32 - shamt)) & 1); + case LSR: + if (shamt == 0) + return (!!cfval); + else if (shamt == 32) + return (base >> 31); + else if (shamt > 32) + return (0); + else + return ((base >> (shamt - 1)) & 1); + case ASR: + if (shamt == 0) + return (!!cfval); + else if (shamt >= 32) + return (base >> 31L); + else + return (((uint32_t) (((int32_t) base) >> (shamt - 1))) & 1); + case ROR: + if (shamt == 0) + return (!!cfval); + shamt = shamt & 0x1f; + if (shamt == 0) + return (base >> 31); // RRX + else + return ((base >> (shamt - 1)) & 1); + default: + fprintf(stderr, "Unhandled shift type\n"); + exit(1); + break; + + } + return 0; +} + + +// Generate the appropriate carry bit for an addition operation +int32_t +ArmStaticInst::arm_add_carry(int32_t result, int32_t lhs, int32_t rhs) const +{ + if ((lhs | rhs) >> 30) + return ((arm_NEG(lhs) && arm_NEG(rhs)) || + (arm_NEG(lhs) && arm_POS(result)) || + (arm_NEG(rhs) && arm_POS(result))); + + return 0; +} + +// Generate the appropriate carry bit for a subtraction operation +int32_t +ArmStaticInst::arm_sub_carry(int32_t result, int32_t lhs, int32_t rhs) const +{ + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) + return ((arm_NEG(lhs) && arm_POS(rhs)) || + (arm_NEG(lhs) && arm_POS(result)) || + (arm_POS(rhs) && arm_POS(result))); + + return 0; +} + +int32_t +ArmStaticInst::arm_add_overflow(int32_t result, int32_t lhs, int32_t rhs) const +{ + if ((lhs | rhs) >> 30) + return ((arm_NEG(lhs) && arm_NEG(rhs) && arm_POS(result)) || + (arm_POS(lhs) && arm_POS(rhs) && arm_NEG(result))); + + return 0; +} + +int32_t +ArmStaticInst::arm_sub_overflow(int32_t result, int32_t lhs, int32_t rhs) const +{ + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) + return ((arm_NEG(lhs) && arm_POS(rhs) && arm_POS(result)) || + (arm_POS(lhs) && arm_NEG(rhs) && arm_NEG(result))); + + return 0; +} + +void +ArmStaticInst::printReg(std::ostream &os, int reg) const { if (reg < FP_Base_DepTag) { ccprintf(os, "r%d", reg); @@ -41,8 +262,9 @@ void ArmStaticInst::printReg(std::ostream &os, int reg) const } } -std::string ArmStaticInst::generateDisassembly(Addr pc, - const SymbolTable *symtab) const +std::string +ArmStaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { std::stringstream ss; diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index 5c88657b8..9ee166ecb 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -34,22 +34,55 @@ namespace ArmISA { - class ArmStaticInst : public StaticInst - { - protected: +class ArmStaticInst : public StaticInst +{ + protected: + // Shift Rm by an immediate value + int32_t + shift_rm_imm(uint32_t base, uint32_t shamt, + uint32_t type, uint32_t cfval) const; + + // Shift Rm by Rs + int32_t + shift_rm_rs(uint32_t base, uint32_t shamt, + uint32_t type, uint32_t cfval) const; + + // Generate C for a shift by immediate + int32_t + shift_carry_imm(uint32_t base, uint32_t shamt, + uint32_t type, uint32_t cfval) const; + + // Generate C for a shift by Rs + int32_t + shift_carry_rs(uint32_t base, uint32_t shamt, + uint32_t type, uint32_t cfval) const; - // Constructor - ArmStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) - : StaticInst(mnem, _machInst, __opClass) - { - } + // Generate the appropriate carry bit for an addition operation + int32_t + arm_add_carry(int32_t result, int32_t lhs, int32_t rhs) const; + + // Generate the appropriate carry bit for a subtraction operation + int32_t + arm_sub_carry(int32_t result, int32_t lhs, int32_t rhs) const; + + int32_t + arm_add_overflow(int32_t result, int32_t lhs, int32_t rhs) const; + + int32_t + arm_sub_overflow(int32_t result, int32_t lhs, int32_t rhs) const; + + // Constructor + ArmStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } - /// Print a register name for disassembly given the unique - /// dependence tag number (FP or int). - void printReg(std::ostream &os, int reg) const; + /// Print a register name for disassembly given the unique + /// dependence tag number (FP or int). + void printReg(std::ostream &os, int reg) const; - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; } #endif //__ARCH_ARM_INSTS_STATICINST_HH__ |