diff options
| -rw-r--r-- | qtmips_machine/alu.cpp | 38 | ||||
| -rw-r--r-- | qtmips_machine/instruction.cpp | 75 | ||||
| -rw-r--r-- | qtmips_machine/instruction.h | 2 | ||||
| -rw-r--r-- | qtmips_machine/machinedefs.h | 7 | 
4 files changed, 97 insertions, 25 deletions
| diff --git a/qtmips_machine/alu.cpp b/qtmips_machine/alu.cpp index de38c96..83c94bd 100644 --- a/qtmips_machine/alu.cpp +++ b/qtmips_machine/alu.cpp @@ -98,6 +98,7 @@ std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s,                                     ExceptionCause &excause) {      std::int64_t s64_val;      std::uint64_t u64_val; +    std::uint32_t u32_val;      discard = false;      switch(operation) { @@ -107,16 +108,25 @@ std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s,              return t << sa;          case ALU_OP_SRL:              return t >> sa; +        case ALU_OP_ROTR: +            if (!sa) +                return t; +            return (t >> sa) | (t << (32 - sa));          case ALU_OP_SRA:              // Note: This might be broken with some compilers but works with gcc              return (std::int32_t)t >> sa;          case ALU_OP_SLLV: -            return t << s; +            return t << (s & 0x1f);          case ALU_OP_SRLV: -            return t >> s; +            return t >> (s & 0x1f); +        case ALU_OP_ROTRV: +            u32_val = s & 0x1f; +            if (!u32_val) +                return t; +            return (t >> u32_val) | (t << (32 - u32_val));          case ALU_OP_SRAV:              // Note: same note as in case of SRA -            return (std::int32_t)t >> s; +            return (std::int32_t)t >> (s & 0x1f);          case ALU_OP_MOVZ:              // Signal discard of result when condition is not true              discard = t != 0; @@ -228,19 +238,17 @@ std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s,              return 0;          case ALU_OP_LUI:              return t << 16; -        case ALU_OP_BSHFL: -            switch (sa) { -            case 0x02: -                return ((t << 8) & 0xff00ff00) | ((t >> 8) & 0x00ff00ff); -            case 0x10: -                return (uint32_t)(int32_t)(int8_t)t; -            case 0x18: -                return (uint32_t)(int32_t)(int16_t)t; -            default: -                throw QTMIPS_EXCEPTION(UnsupportedAluOperation, "Unknown BSHFL variant", QString::number(sa, 16)); -            } +        case ALU_OP_WSBH: +            return ((t << 8) & 0xff00ff00) | ((t >> 8) & 0x00ff00ff); +        case ALU_OP_SEB: +            return (uint32_t)(int32_t)(int8_t)t; +        case ALU_OP_SEH: +            return (uint32_t)(int32_t)(int16_t)t;          case ALU_OP_EXT: -            return (s >> sa) & ((1 << sz) - 1); +            return (s >> sa) & ((1 << (sz + 1)) - 1); +        case ALU_OP_INS: +            u32_val = (1 << (sz + 1)) - 1; +            return ((s & u32_val) << sa) | (t & ~(u32_val << sa));          case ALU_OP_CLZ:              return alu_op_clz(s);          case ALU_OP_CLO: diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index d0e0a67..41cfb5c 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -35,6 +35,7 @@  #include <QMultiMap>  #include <QVector> +#include <iostream>  #include "instruction.h"  #include "alu.h"  #include "memory.h" @@ -87,20 +88,34 @@ struct InstructionMap {  #define IT_I Instruction::T_I  #define IT_J Instruction::T_J +static const struct InstructionMap  srl_rotr_instruction_map[] = { +    {"SRL",    IT_R, ALU_OP_SRL, NOMEM, nullptr, +     .flags = FLAGS_ALU_T_R_TD_SHAMT}, +    {"ROTR",   IT_R, ALU_OP_ROTR, NOMEM, nullptr, +     .flags = FLAGS_ALU_T_R_TD_SHAMT}, +}; + +static const struct InstructionMap  srlv_rotrv_instruction_map[] = { +    {"SRLV",   IT_R, ALU_OP_SRLV, NOMEM, nullptr, +     .flags = FLAGS_ALU_T_R_STD_SHV}, +    {"ROTRV",   IT_R, ALU_OP_ROTRV, NOMEM, nullptr, +     .flags = FLAGS_ALU_T_R_STD_SHV}, +}; +  // This table is indexed by funct  static const struct InstructionMap  alu_instruction_map[] = {      {"SLL",    IT_R, ALU_OP_SLL, NOMEM, nullptr,       .flags = FLAGS_ALU_T_R_TD_SHAMT},      IM_UNKNOWN, -    {"SRL",    IT_R, ALU_OP_SRL, NOMEM, nullptr, -     .flags = FLAGS_ALU_T_R_TD_SHAMT}, +    {"SRL",    IT_R, ALU_OP_SRL, NOMEM, srl_rotr_instruction_map, +     .flags = IMF_SUB_ENCODE(1, 21)},      {"SRA",    IT_R, ALU_OP_SRA, NOMEM, nullptr,       .flags = FLAGS_ALU_T_R_TD_SHAMT},      {"SLLV",   IT_R, ALU_OP_SLLV, NOMEM, nullptr,       .flags = FLAGS_ALU_T_R_STD_SHV},      IM_UNKNOWN, -    {"SRLV",   IT_R, ALU_OP_SRLV, NOMEM, nullptr, -     .flags = FLAGS_ALU_T_R_STD_SHV}, +    {"SRLV",   IT_R, ALU_OP_SRLV, NOMEM, srlv_rotrv_instruction_map, +     .flags = IMF_SUB_ENCODE(1, 6)},      {"SRAV",   IT_R, ALU_OP_SRAV, NOMEM, nullptr,       .flags = FLAGS_ALU_T_R_STD_SHV},      {"JR",     IT_R, ALU_OP_NOP, NOMEM, nullptr, @@ -195,7 +210,7 @@ static const struct InstructionMap  alu_instruction_map[] = {  static const struct InstructionMap  special2_instruction_map[] = {      {"MADD",    IT_R, ALU_OP_MADD, NOMEM, nullptr,       .flags = FLAGS_ALU_T_R_ST | IMF_READ_HILO | IMF_WRITE_HILO}, -    {"MADD",    IT_R, ALU_OP_MADDU, NOMEM, nullptr, +    {"MADDU",   IT_R, ALU_OP_MADDU, NOMEM, nullptr,       .flags = FLAGS_ALU_T_R_ST | IMF_READ_HILO | IMF_WRITE_HILO},      {"MUL",     IT_R, ALU_OP_MUL, NOMEM, nullptr,       .flags = FLAGS_ALU_T_R_STD},     // 32 @@ -266,13 +281,52 @@ static const struct InstructionMap  special2_instruction_map[] = {      IM_UNKNOWN,	//	63  }; +static const struct InstructionMap  bshfl_instruction_map[] = { +    IM_UNKNOWN,	//	0 +    IM_UNKNOWN,	//	1 +    {"WSBH", IT_R, ALU_OP_WSBH, NOMEM, nullptr, +     .flags = FLAGS_ALU_T_R_TD}, +    IM_UNKNOWN,	//	3 +    IM_UNKNOWN,	//	4 +    IM_UNKNOWN,	//	5 +    IM_UNKNOWN,	//	6 +    IM_UNKNOWN,	//	7 +    IM_UNKNOWN,	//	8 +    IM_UNKNOWN,	//	9 +    IM_UNKNOWN,	//	10 +    IM_UNKNOWN,	//	11 +    IM_UNKNOWN,	//	12 +    IM_UNKNOWN,	//	13 +    IM_UNKNOWN,	//	14 +    IM_UNKNOWN,	//	15 +    {"SEB", IT_R, ALU_OP_SEB, NOMEM, nullptr, +     .flags = FLAGS_ALU_T_R_TD}, +    IM_UNKNOWN,	//	17 +    IM_UNKNOWN,	//	18 +    IM_UNKNOWN,	//	19 +    IM_UNKNOWN,	//	20 +    IM_UNKNOWN,	//	21 +    IM_UNKNOWN,	//	22 +    IM_UNKNOWN,	//	23 +    {"SEH", IT_R, ALU_OP_SEH, NOMEM, nullptr, +     .flags = FLAGS_ALU_T_R_TD}, +    IM_UNKNOWN,	//	25 +    IM_UNKNOWN,	//	26 +    IM_UNKNOWN,	//	27 +    IM_UNKNOWN,	//	28 +    IM_UNKNOWN,	//	29 +    IM_UNKNOWN,	//	30 +    IM_UNKNOWN,	//	31 +}; +  static const struct InstructionMap  special3_instruction_map[] = {      {"EXT", IT_I, ALU_OP_EXT, NOMEM, nullptr,       .flags = IMF_SUPPORTED | IMF_REGWRITE | IMF_ALU_REQ_RS},      IM_UNKNOWN,	//	1      IM_UNKNOWN,	//	2      IM_UNKNOWN,	//	3 -    IM_UNKNOWN,	//	4 +    {"INS", IT_I, ALU_OP_EXT, NOMEM, nullptr, +     .flags = IMF_SUPPORTED | IMF_REGWRITE | IMF_ALU_REQ_RS | IMF_ALU_REQ_RT},      IM_UNKNOWN,	//	5      IM_UNKNOWN,	//	6      IM_UNKNOWN,	//	7 @@ -300,8 +354,8 @@ static const struct InstructionMap  special3_instruction_map[] = {      IM_UNKNOWN,	//	29      IM_UNKNOWN,	//	30      IM_UNKNOWN,	//	31 -    {"BSHFL", IT_R, ALU_OP_BSHFL, NOMEM, nullptr, -     .flags = FLAGS_ALU_T_R_TD}, +    {"BSHFL", IT_I, NOALU, NOMEM, bshfl_instruction_map, +     .flags = IMF_SUB_ENCODE(5, 6)},      IM_UNKNOWN,	//	33      IM_UNKNOWN,	//	34      IM_UNKNOWN,	//	35 @@ -759,6 +813,11 @@ void instruction_from_string_build_base(const InstructionMap *im = nullptr,              continue;          str_to_instruction_code_map.insert(im->name, code);      } +#if 0 +    for (auto i = str_to_instruction_code_map.begin(); +         i != str_to_instruction_code_map.end(); i++) +        std::cout << i.key().toStdString() << ' '; +#endif  }  static int parse_reg_from_string(QString str) diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h index 0d76eeb..b7ae4bd 100644 --- a/qtmips_machine/instruction.h +++ b/qtmips_machine/instruction.h @@ -37,7 +37,7 @@  #define INSTRUCTION_H  #include <QObject> -#include <qstring.h> +#include <QString>  #include "machinedefs.h" diff --git a/qtmips_machine/machinedefs.h b/qtmips_machine/machinedefs.h index bad585f..f575648 100644 --- a/qtmips_machine/machinedefs.h +++ b/qtmips_machine/machinedefs.h @@ -70,9 +70,11 @@ enum AluOp : std::uint8_t {      ALU_OP_NOP,      ALU_OP_SLL,      ALU_OP_SRL, +    ALU_OP_ROTR,      ALU_OP_SRA,      ALU_OP_SLLV,      ALU_OP_SRLV, +    ALU_OP_ROTRV,      ALU_OP_SRAV,      ALU_OP_MOVZ,      ALU_OP_MOVN, @@ -106,8 +108,11 @@ enum AluOp : std::uint8_t {      ALU_OP_TEQ,      ALU_OP_TNE,      ALU_OP_LUI, -    ALU_OP_BSHFL, +    ALU_OP_WSBH, +    ALU_OP_SEB, +    ALU_OP_SEH,      ALU_OP_EXT, +    ALU_OP_INS,      ALU_OP_CLZ,      ALU_OP_CLO,      ALU_OP_PASS_T, // Pass t argument without change for JAL | 
