From db6d1315bf93746b5804ab11ae102d2800882667 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:21:04 +0530 Subject: [PATCH] arch-power: Refactor logical instructions This changes the base class for integer logical instructions and adds a new class that is used to distinguish between instructions using different operand types, i.e. register or immediate. The formats have also been updated to make use of the new base classes. Change-Id: Id780cdb16405b01e82dcd22dc6e885ee15b716b2 Signed-off-by: Sandipan Das --- src/arch/power/insts/integer.hh | 48 ++++++++++++++++++++++++++ src/arch/power/isa/formats/integer.isa | 44 ++++++++++++++--------- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index 2cf35ab9c..d310e7340 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -491,6 +491,54 @@ class IntImmCompLogicOp : public IntCompOp }; +/** + * Class for integer logical operations. + */ +class IntLogicOp : public IntOp +{ + protected: + + /// Constructor + IntLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntOp(mnem, _machInst, __opClass) + { + } + + inline int + findLeadingZeros(uint32_t rs) const + { + if (rs) { + #if defined(__GNUC__) || (defined(__clang__) && \ + __has_builtin(__builtin_clz)) + return __builtin_clz(rs); + #else + return 31 - findMsbSet(rs); + #endif + } else { + return 32; + } + } +}; + + +/** + * Class for integer immediate logical operations. + */ +class IntImmLogicOp : public IntLogicOp +{ + protected: + + uint32_t uimm; + + /// Constructor + IntImmLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntLogicOp(mnem, _machInst, __opClass), + uimm(machInst.si) + { + } +}; + + /** * Class for integer operations with a shift. */ diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa index 87763698b..286c1cf98 100644 --- a/src/arch/power/isa/formats/integer.isa +++ b/src/arch/power/isa/formats/integer.isa @@ -196,12 +196,14 @@ def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{ # Set up the dictionary and deal with computing CR0 dict = {'result':'Ra'} + + # Code when Rc is set if computeCR0: code += readXERCode + computeCR0Code % dict # Generate the class (header_output, decoder_output, decode_block, exec_output) = \ - GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + GenAluOp(name, Name, 'IntImmLogicOp', code, inst_flags, BasicDecode, BasicConstructor) }}; @@ -269,29 +271,37 @@ def format IntImmCompLogicOp(code, inst_flags = []) {{ // Integer instructions that perform logic operations. The result is -// always written into Ra. All instructions have 2 versions depending on +// always written into Ra. Some instructions have 2 versions depending on // whether the Rc bit is set to compute the CR0 code. This is determined // at decode as before. -def format IntLogicOp(code, inst_flags = []) {{ +def format IntLogicOp(code, computeCR0 = 0, inst_flags = []) {{ dict = {'result':'Ra'} - # Code when Rc is set - code_rc1 = code + readXERCode + computeCR0Code % dict + # Deal with computing CR0 + if computeCR0: + # Setup the 2 code versions and add code to access XER if necessary + code_rc1 = code + readXERCode + computeCR0Code % dict - # Generate the first class - (header_output, decoder_output, decode_block, exec_output) = \ - GenAluOp(name, Name, 'IntOp', code, inst_flags, - CheckRcDecode, BasicConstructor) + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntLogicOp', code, inst_flags, + CheckRcDecode, BasicConstructor) - # Generate the second class - (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ - GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, - CheckRcDecode, IntRcConstructor) + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntLogicOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) - # Finally, add to the other outputs - header_output += header_output_rc1 - decoder_output += decoder_output_rc1 - exec_output += exec_output_rc1 + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 + + else: + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntLogicOp', code, inst_flags, + BasicDecode, BasicConstructor) }}; -- 2.30.2