#define sign_extend(N,SIZE) (((int)((N) << (sizeof(unsigned)*8-(SIZE)))) >> (sizeof(unsigned)*8-(SIZE)))
#include <assert.h>

#line 1 "machine/hppa/decoder.m"
/*==============================================================================
 * FILE:       decoder.m
 * OVERVIEW:   Implementation of the HP pa-risc specific parts of the
 *             NJMCDecoder class.
 *
 * (C) 1996-2001 The University of Queensland, BT Group
 *============================================================================*/

/* $Revision: 1.1 $
 *
 *    Apr 01 - Simon: Created
 * 04 May 01 - Mike: Create RTLs not strings; moved addressing mode functions
 *                      here (from decoder_low.m)
 * 08 May 01 - Mike: New addressing modes for dis_addr handles "modify"
 * 09 May 01 - Mike: Match several logues; add idReg where needed; fixed ma
 *              addressing mode
 * 11 May 01 - Mike: Match branches as high level jumps
 * 13 May 01 - Mike: Fixed problems with B.l.n
 * 14 May 01 - Mike: Added some early code for cmpib_all
 * 17 May 01 - Mike: Added gcc frameless logues; handle non anulled CMPIB
 * 27 Jun 01 - Mike: B.l -> BL (1.1 opcode) etc; addressing modes too
 * 19 Jul 01 - Simon: Updated dis_addr(). Added dis_x_addr_shift().
 * 19 Jul 01 - Simon: Also got cmpibf working with various conditions.
 * 23 Jul 01 - Simon: Added cmpb_all and addr_ldisp_17_old
 * 01 Aug 01 - Mike: BL with no target register treated as branch, not call
 * 06 Aug 01 - Mike: Added ADD[I]B; removed getBump()
 * 07 Aug 01 - Mike: Added bare_ret, bare_ret_anulled patterns; some patterns
 *              are type DU now; fixed SCDAN cases
 * 07 Aug 01 - Simon: dis_addr() gone completely - [addr] => [xd,s,b]
 * 10 Aug 01 - Simon: added dis_c_bit(); added BB/BVB High Level Branches
 * 20 Aug 01 - Mike: Check for param_reloc1 pattern
 */

#include "global.h"
#include "proc.h"
#include "prog.h"
#include "decoder.h"
#include "ss.h"
#include "rtl.h"
#include "csr.h"
#include "hppa.pat.h"      // generated from `sparc.pat'
#include "hppa-names.h"    // generated by 'tools -fieldnames' - has
                            //   arrays of names of fields
#include "BinaryFile.h"     // For SymbolByAddress()


static const JCOND_TYPE hl_jcond_type[] = {
    HLJCOND_JNE, // no 'jump_never' enumeration for JCOND_TYPE
    HLJCOND_JE,
    HLJCOND_JSL,
    HLJCOND_JSLE,
    HLJCOND_JUL,
    HLJCOND_JULE,
    HLJCOND_JOF,
    HLJCOND_JNE, // no 'jump_if_odd' enumeration for JCOND_TYPE
    HLJCOND_JE,
    HLJCOND_JNE,
    HLJCOND_JSGE,
    HLJCOND_JSG,
    HLJCOND_JUGE,
    HLJCOND_JUG,
    HLJCOND_JNOF,
    HLJCOND_JE  // no 'jump_if_even' enumeration for JCOND_TYPE
};

// Handle the completer for the addr addressing mode
void c_addr(ADDRESS hostpc, SemStr* ssb, SemStr* ssx);

bool is_null(ADDRESS hostPC)
{
    bool res;


#line 71 "machine/hppa/decoder.m"
{ 
  dword MATCH_p = 
    
#line 71 "machine/hppa/decoder.m"
    hostPC
    ;
  unsigned MATCH_w_32_0;
  { 
    MATCH_w_32_0 = getDword(MATCH_p); 
    
      switch((MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */) {
        case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 
        case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: 
        case 16: case 17: case 18: case 19: case 20: case 21: case 22: 
        case 23: case 24: case 25: case 26: case 27: case 28: case 29: 
        case 30: case 31: case 36: case 37: case 38: case 44: case 45: 
        case 46: case 52: case 53: case 54: case 55: case 60: case 61: 
        case 62: case 63: 
          assert(0);  /* no match */break;
        case 32: case 33: case 34: case 35: case 39: case 40: case 41: 
        case 42: case 43: case 47: case 48: case 49: case 50: case 51: 
        case 56: case 57: case 58: case 59: 
          if ((MATCH_w_32_0 >> 1 & 0x1) /* n_30 at 0 */ == 1) 
            
#line 76 "machine/hppa/decoder.m"
             {

                        res = true;

                    }

            
             /*opt-block+*/
          else 
            
#line 73 "machine/hppa/decoder.m"
             {

                        res = false;

                    }

            
             /*opt-block+*/
          
          break;
        default: assert(0);
      } /* (MATCH_w_32_0 >> 26 & 0x3f) -- op at 0 --*/ 
    
  }goto MATCH_finished_e; 
  
  MATCH_finished_e: (void)0; /*placeholder for label*/
  
}

#line 80 "machine/hppa/decoder.m"

    return res;
}


DecodeResult& NJMCDecoder::decodeInstruction (ADDRESS pc, int delta,
    UserProc* proc /* = NULL */)
{ 
    static DecodeResult result;
    ADDRESS hostPC = pc+delta;

    // Clear the result structure;
    result.reset();

    // The actual list of instantiated RTs
    list<RT*>* RTs = NULL;
    preInstSem = NULL;          // No semantics before the instruction yet
    postInstSem = NULL;         // No semantics after the instruction yet

    ADDRESS nextPC;

    // Try matching a logue first.
    ADDRESS saveHostPC = hostPC;
    int addr, locals, libstub;
    Logue* logue;

    if ((logue = InstructionPatterns::std_call(csr,hostPC,addr)) != NULL) {
        /*
         * Ordinary call to fixed dest
         */
        HLCall* newCall = new HLCall(pc, 0, RTs);
        // Set the fixed destination. Note that addr is (at present!!) just
        // the offset in the instruction, so we have to add native pc
        newCall->setDest(addr + pc);
        result.numBytes = hostPC - saveHostPC;
        // See if this call is to a special symbol
        const char* dest = prog.pBF->SymbolByAddress((ADDRESS)(addr + pc));
        if (dest && (strcmp(dest, "__main") == 0)) {
            // Treat this as a NOP
        } else {

            result.rtl = newCall;
            result.type = SD;

            // Record the prologue of this caller
            newCall->setPrologue(logue);

            SHOW_ASM("std_call 0x" << hex << addr-delta)
        }
    }

    //
    // Callee prologues
    //
    else if ((logue = InstructionPatterns::gcc_frame(csr,hostPC, locals))
      != NULL) {
        /*
         * Standard prologue for gcc: sets up frame in %r3; optionally saves
         * several registers to the stack
         */
        if (proc != NULL) {

            // Record the prologue of this callee
            assert(logue->getType() == Logue::CALLEE_PROLOGUE);
            proc->setPrologue((CalleePrologue*)logue);
        }

        result.numBytes = hostPC - saveHostPC;
        result.rtl = new RTL(pc,RTs);
        result.type = NCT;
        SHOW_ASM("gcc_frame " << dec << locals)
    }
    else if ((logue = InstructionPatterns::gcc_frameless(csr,hostPC, locals))
      != NULL) {
        /*
         * Gcc prologue where optimisation is on, and no frame pointer is needed
         */
        if (proc != NULL) {

            // Record the prologue of this callee
            assert(logue->getType() == Logue::CALLEE_PROLOGUE);
            proc->setPrologue((CalleePrologue*)logue);
        }

        result.numBytes = hostPC - saveHostPC;
        result.rtl = new RTL(pc,RTs);
        result.type = NCT;
        SHOW_ASM("gcc_frameless " << dec << locals)
    }
    else if ((locals=8, logue = InstructionPatterns::param_reloc1(csr,hostPC,
      libstub, locals)) != NULL) {
        /*
         * Parameter relocation stub common when passing a double as the second
         * parameter to printf
         */
        if (proc != NULL) {
            // Record the prologue of this callee
            assert(logue->getType() == Logue::CALLEE_PROLOGUE);
            proc->setPrologue((CalleePrologue*)logue);
        }

        // The semantics of the first 3 instructions are difficult to translate
        // However, they boil down to these three, and the parameter analysis
        // should be able to use these:
        // *64* m[%afp + 0] = r[39];
        SemStr* ssSrc = new SemStr;
        SemStr* ssDst = new SemStr;
        *ssSrc << idRegOf << idIntConst << 39;
        *ssDst << idMemOf << idAFP;
        RTs = new list<RT*>;
        RTAssgn* pRt = new RTAssgn(ssDst, ssSrc, 64); RTs->push_back(pRt);
        // *32* r[23] := m[%afp    ];
        ssSrc = new SemStr; ssDst = new SemStr;
        *ssSrc << idMemOf << idAFP;
        *ssDst << idRegOf << idIntConst << 23;
        pRt = new RTAssgn(ssDst, ssSrc, 32);
        RTs->push_back(pRt);
        // *32* r[24] := m[%afp + 4];
        ssSrc = new SemStr; ssDst = new SemStr;
        *ssSrc << idMemOf << idPlus << idAFP << idIntConst << 4;
        *ssDst << idRegOf << idIntConst << 24;
        pRt = new RTAssgn(ssDst, ssSrc, 32); RTs->push_back(pRt);

        // Find the destination of the final jump. It starts 12 bytes later than
        // the pc of the whole pattern
        ADDRESS dest = pc + 12 + libstub;
        // Treat it like a call, followed by a return
        HLCall* newCall = new HLCall(pc, 0, RTs);
        // Set the fixed destination.
        newCall->setDest(dest);
        newCall->setReturnAfterCall(true);
        result.numBytes = hostPC - saveHostPC;
        result.rtl = newCall;
        result.type = SU;

        // Record the prologue of this caller (though it's the wrong type)
        newCall->setPrologue(logue);
        SHOW_ASM("param_reloc1 " << hex << dest)
    }

    //
    // Callee epilogues
    //
    else if ((logue = InstructionPatterns::gcc_unframe(csr, hostPC)) != NULL) {
        /*
         * Standard removal of current frame for gcc; optional restore of
         * several registers from stack
         */
        result.numBytes = hostPC - saveHostPC;
        result.rtl = new HLReturn(pc,RTs);
        result.type = DU;

        // Record the epilogue of this callee
        if (proc != NULL) {
            assert(logue->getType() == Logue::CALLEE_EPILOGUE);
            proc->setEpilogue((CalleeEpilogue*)logue);
        }
    
        SHOW_ASM("gcc_unframe");
    }
    else if ((logue = InstructionPatterns::gcc_unframeless1(csr, hostPC)) !=
      NULL) {
        /*
         * Removal of current frame for gcc (where no frame pointer was used)
         */
        result.numBytes = hostPC - saveHostPC;
        result.rtl = new HLReturn(pc,RTs);
        // Although the actual return instruction is a DD (Dynamic Delayed
        // branch), we call it a DU so the delay slot instruction is not decoded
        result.type = DU;

        // Record the epilogue of this callee
        if (proc != NULL) {
            assert(logue->getType() == Logue::CALLEE_EPILOGUE);
            proc->setEpilogue((CalleeEpilogue*)logue);
        }
    
        SHOW_ASM("gcc_unframeless1");
    }
    else if ((logue = InstructionPatterns::gcc_unframeless2(csr, hostPC)) !=
      NULL) {
        /*
         * Removal of current frame for gcc (where no frame pointer was used)
         */
        result.numBytes = hostPC - saveHostPC;
        result.rtl = new HLReturn(pc,RTs);
        result.type = DU;

        // Record the epilogue of this callee
        if (proc != NULL) {
            assert(logue->getType() == Logue::CALLEE_EPILOGUE);
            proc->setEpilogue((CalleeEpilogue*)logue);
        }
    
        SHOW_ASM("gcc_unframeless2");
    }
    else if ((logue = InstructionPatterns::bare_ret(csr, hostPC)) != NULL) {
        /*
         * Just a bare (non anulled) return statement
         */
        result.numBytes = 8;        // BV and the delay slot instruction
        result.rtl = new HLReturn(pc, RTs);
        // This is a DD instruction; the front end will decode the delay slot
        // instruction
        result.type = DD;

        // Record the epilogue of this callee
        if (proc != NULL) {
            assert(logue->getType() == Logue::CALLEE_EPILOGUE);
            proc->setEpilogue((CalleeEpilogue*)logue);
        }
    
        SHOW_ASM("bare_ret");
    }
    else if ((logue = InstructionPatterns::bare_ret_anulled(csr, hostPC))
      != NULL) {
        /*
         * Just a bare (anulled) return statement
         */
        result.numBytes = 4;        // BV only
        result.rtl = new HLReturn(pc, RTs);
        result.type = DU;       // No delay slot to decode

        // Record the epilogue of this callee
        if (proc != NULL) {
            assert(logue->getType() == Logue::CALLEE_EPILOGUE);
            proc->setEpilogue((CalleeEpilogue*)logue);
        }
    
        SHOW_ASM("bare_ret_anulled");
    }

    else {
        // Branches and other high level instructions


#line 313 "machine/hppa/decoder.m"
{ 
  dword MATCH_p = 
    
#line 313 "machine/hppa/decoder.m"
    hostPC
    ;
  char *MATCH_name;
  unsigned MATCH_w_32_0;
  { 
    MATCH_w_32_0 = getDword(MATCH_p); 
    
      switch((MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */) {
        case 0: case 1: case 3: case 4: case 5: case 6: case 7: case 8: 
        case 9: case 10: case 11: case 12: case 13: case 14: case 15: 
        case 16: case 17: case 18: case 19: case 20: case 21: case 22: 
        case 23: case 24: case 25: case 26: case 27: case 28: case 29: 
        case 30: case 31: case 38: case 46: case 52: case 53: case 54: 
        case 55: case 56: case 57: case 60: case 61: case 62: case 63: 
          goto MATCH_label_d0; break;
        case 2: 
          if (1 <= (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ && 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ < 4 || 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ == 6 || 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ == 18 || 
            32 <= (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ && 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ < 34 || 
            35 <= (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ && 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ < 38 || 
            44 <= (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ && 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ < 46 || 
            49 <= (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ && 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ < 51 || 
            53 <= (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ && 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ < 56 || 
            61 <= (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ && 
            (MATCH_w_32_0 >> 6 & 0x3f) /* ext6_20 at 0 */ < 64) 
            goto MATCH_label_d0;  /*opt-block+*/
          else { 
            unsigned cmplt = addressToPC(MATCH_p);
            unsigned r_06 = (MATCH_w_32_0 >> 21 & 0x1f) /* r_06 at 0 */;
            unsigned r_11 = (MATCH_w_32_0 >> 16 & 0x1f) /* r_11 at 0 */;
            unsigned t_27 = (MATCH_w_32_0 & 0x1f) /* t_27 at 0 */;
            nextPC = 4 + MATCH_p; 
            
#line 470 "machine/hppa/decoder.m"
             {

                        // Decode the instruction

                        low_level(RTs, hostPC, pc, result, nextPC);

                        int condvalue;

                        c_c(cmplt, condvalue);

                        if (condvalue != 0)

                            // Anulled. Need to decode the next instruction, and make each

                            // RTAssgn in it conditional on !r[tmpNul]

                            // We can't do this here, so we just make result.type equal to

                            // NCTA, and the front end will do this for us

                            result.type = NCTA;

                        not_used(r_11); not_used(r_06); not_used(t_27);

                    }

            
            
            
          } /*opt-block*//*opt-block+*/
          
          break;
        case 32: case 34: case 39: case 47: 
          { 
            unsigned c_cmplt = addressToPC(MATCH_p);
            unsigned null_cmplt = addressToPC(MATCH_p);
            unsigned r1 = (MATCH_w_32_0 >> 16 & 0x1f) /* r_11 at 0 */;
            unsigned r2 = (MATCH_w_32_0 >> 21 & 0x1f) /* r_06 at 0 */;
            unsigned target = 
              ((MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */ << 2) + 
              ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 12) + 
              ((sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 
                          1) & 0x7ffff) << 13);
            nextPC = 4 + MATCH_p; 
            
#line 369 "machine/hppa/decoder.m"
             {

                        int condvalue;

                        SemStr* cond_ss = c_c(c_cmplt, condvalue);

                        HLJcond* jump = new HLJcond(pc, RTs);

                        jump->setCondType(hl_jcond_type[condvalue]);

                        jump->setDest(dis_Num(target + pc + 8));

                        SemStr* reg1 = dis_Reg(r1);

                        SemStr* reg2 = dis_Reg(r2);

                        reg1->prep(idRegOf);

                        reg2->prep(idRegOf);

                        SemStr* exp = new SemStr;

                        *exp << idMinus << *reg1 << *reg2;

                        substituteCallArgs("c_c", cond_ss, reg1, reg2, exp);

                        jump->setCondExpr(cond_ss);

                        bool isNull = is_null(null_cmplt);

                        // If isNull, then taken forward or failing backwards anull

                        result.type = isNull ? (((int)target >= 0) ? SCDAT : SCDAN) : SCD;

                        result.rtl = jump;

                        result.numBytes = 4;

                    }

            
            
            
          }
          
          break;
        case 33: case 35: case 59: 
          { 
            unsigned c_cmplt = addressToPC(MATCH_p);
            unsigned im5_11 = 
              ((sign_extend((MATCH_w_32_0 >> 16 & 0x1) /* im1_15 at 0 */, 
                          1) & 0xfffffff) << 4) + 
              (MATCH_w_32_0 >> 17 & 0xf) /* im4_11 at 0 */;
            unsigned null_cmplt = addressToPC(MATCH_p);
            unsigned r_06 = (MATCH_w_32_0 >> 21 & 0x1f) /* r_06 at 0 */;
            unsigned target = 
              ((MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */ << 2) + 
              ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 12) + 
              ((sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 
                          1) & 0x7ffff) << 13);
            nextPC = 4 + MATCH_p; 
            
#line 349 "machine/hppa/decoder.m"
             {

                        int condvalue;

                        SemStr* cond_ss = c_c(c_cmplt, condvalue);

                        HLJcond* jump = new HLJcond(pc, RTs);

                        jump->setCondType(hl_jcond_type[condvalue]);

                        jump->setDest(dis_Num(target + pc + 8));

                        SemStr* imm = dis_Num(im5_11);

                        SemStr* reg = dis_Reg(r_06);

                        reg->prep(idRegOf);

                        SemStr* exp = new SemStr;

                        *exp << idMinus << *imm << *reg;

                        substituteCallArgs("c_c", cond_ss, imm, reg, exp);

                        jump->setCondExpr(cond_ss);

                        bool isNull = is_null(null_cmplt);

                        // If isNull, then taken forward or failing backwards anull

                        result.type = isNull ? (((int)target >= 0) ? SCDAT : SCDAN) : SCD;

                        result.rtl = jump;

                        result.numBytes = 4;

                    }

            

            
            
            
          }
          
          break;
        case 36: 
          goto MATCH_label_d1; break;
        case 37: case 44: case 45: 
          goto MATCH_label_d1; break;
        case 40: 
          MATCH_name = "ADDBT"; goto MATCH_label_d2; break;
        case 41: 
          MATCH_name = "ADDIBT"; goto MATCH_label_d3; break;
        case 42: 
          MATCH_name = "ADDBF"; goto MATCH_label_d2; break;
        case 43: 
          MATCH_name = "ADDIBF"; goto MATCH_label_d3; break;
        case 48: 
          goto MATCH_label_d4; break;
        case 49: 
          if ((MATCH_w_32_0 >> 13 & 0x1) /* d_18 at 0 */ == 1) 
            goto MATCH_label_d0;  /*opt-block+*/
          else 
            goto MATCH_label_d4;  /*opt-block+*/
          
          break;
        case 50: 
          MATCH_name = "MOVB"; 
          { 
            char *name = MATCH_name;
            unsigned c_cmplt = addressToPC(MATCH_p);
            unsigned null_cmplt = addressToPC(MATCH_p);
            unsigned r1 = (MATCH_w_32_0 >> 16 & 0x1f) /* r_11 at 0 */;
            unsigned r2 = (MATCH_w_32_0 >> 21 & 0x1f) /* r_06 at 0 */;
            unsigned target = 
              ((MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */ << 2) + 
              ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 12) + 
              ((sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 
                          1) & 0x7ffff) << 13);
            nextPC = 4 + MATCH_p; 
            
#line 409 "machine/hppa/decoder.m"
             {

                        int condvalue;

                        SemStr* cond_ss = c_c(c_cmplt, condvalue);

                        RTs = instantiate(pc, name, dis_Reg(r1), dis_Reg(r2));

                        HLJcond* jump = new HLJcond(pc, RTs);

                        jump->setCondType(hl_jcond_type[condvalue]);

                        jump->setDest(dis_Num(target + pc + 8));

                        SemStr* reg1 = dis_Reg(r1);

                        SemStr* reg2 = dis_Reg(r2);

                        reg1->prep(idRegOf);

                        reg2->prep(idRegOf);

                        SemStr* tgt = new SemStr(*reg2);

                        substituteCallArgs("c_c", cond_ss, reg1, reg2, tgt);

                        jump->setCondExpr(cond_ss);

                        bool isNull = is_null(null_cmplt);

                        result.type = isNull ? (((int)target >= 0) ? SCDAT : SCDAN) : SCD;

                        result.rtl = jump;

                        result.numBytes = 4;

                    }

            
            
            
          }
          
          break;
        case 51: 
          MATCH_name = "MOVIB"; 
          { 
            char *name = MATCH_name;
            unsigned c_cmplt = addressToPC(MATCH_p);
            unsigned i = 
              ((sign_extend((MATCH_w_32_0 >> 16 & 0x1) /* im1_15 at 0 */, 
                          1) & 0xfffffff) << 4) + 
              (MATCH_w_32_0 >> 17 & 0xf) /* im4_11 at 0 */;
            unsigned null_cmplt = addressToPC(MATCH_p);
            unsigned r = (MATCH_w_32_0 >> 21 & 0x1f) /* r_06 at 0 */;
            unsigned target = 
              ((MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */ << 2) + 
              ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 12) + 
              ((sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 
                          1) & 0x7ffff) << 13);
            nextPC = 4 + MATCH_p; 
            
#line 428 "machine/hppa/decoder.m"
             {

                        int condvalue;

                        SemStr* cond_ss = c_c(c_cmplt, condvalue);

                        RTs = instantiate(pc, name, dis_Num(i), dis_Reg(r));

                        HLJcond* jump = new HLJcond(pc, RTs);

                        jump->setCondType(hl_jcond_type[condvalue]);

                        jump->setDest(dis_Num(target + pc + 8));

                        SemStr* imm = dis_Reg(i);

                        SemStr* reg = dis_Reg(r);

                        imm->prep(idIntConst);

                        reg->prep(idRegOf);

                        SemStr* tgt = new SemStr(*reg);

                        substituteCallArgs("c_c", cond_ss, imm, reg, tgt);

                        jump->setCondExpr(cond_ss);

                        bool isNull = is_null(null_cmplt);

                        result.type = isNull ? (((int)target >= 0) ? SCDAT : SCDAN) : SCD;

                        result.rtl = jump;

                        result.numBytes = 4;

                    }

            
            
            
          }
          
          break;
        case 58: 
          if (1 <= (MATCH_w_32_0 >> 13 & 0x7) /* ext3_16 at 0 */ && 
            (MATCH_w_32_0 >> 13 & 0x7) /* ext3_16 at 0 */ < 8) 
            goto MATCH_label_d0;  /*opt-block+*/
          else { 
            unsigned nulli = addressToPC(MATCH_p);
            unsigned t_06 = (MATCH_w_32_0 >> 21 & 0x1f) /* t_06 at 0 */;
            unsigned ubr_target = 
              8 + ((MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */ << 2) + 
              ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 12) + 
              ((MATCH_w_32_0 >> 16 & 0x1f) /* w5_11 at 0 */ << 13) + 
              (sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 1) << 18);
            nextPC = 4 + MATCH_p; 
            
#line 315 "machine/hppa/decoder.m"
             {

                        HLJump* jump;

                        // The return registers are 2 (standard) or 31 (millicode)

                        if ((t_06 == 2) || (t_06 == 31))

                            jump = new HLCall(pc, 0, RTs);

                        if ((t_06 != 2) && (t_06 != 31))    // Can't use "else"

                            jump = new HLJump(pc, RTs);

                        result.rtl = jump;

                        bool isNull = is_null(nulli);

                        if (isNull)

                            result.type = SU;

                        if (!isNull)                        // Can't use "else"

                            result.type = SD;

                        jump->setDest(ubr_target + pc);     // This may change

                        result.numBytes = 4;

                    }

                    

            
            
            
          } /*opt-block*//*opt-block+*/
          
          break;
        default: assert(0);
      } /* (MATCH_w_32_0 >> 26 & 0x3f) -- op at 0 --*/ 
    
  }goto MATCH_finished_d; 
  
  MATCH_label_d0: (void)0; /*placeholder for label*/ 
    { 
      nextPC = MATCH_p; 
      
#line 494 "machine/hppa/decoder.m"
      {

                  // Low level instruction

                  low_level(RTs, hostPC, pc, result, nextPC);

              }

      
      
      
    } 
    goto MATCH_finished_d; 
    
  MATCH_label_d1: (void)0; /*placeholder for label*/ 
    { 
      unsigned cmplt = addressToPC(MATCH_p);
      unsigned imm11 = 
        (sign_extend((MATCH_w_32_0 & 0x1) /* i_31 at 0 */, 1) << 10) + 
        (MATCH_w_32_0 >> 1 & 0x3ff) /* im10_21 at 0 */;
      unsigned r_06 = (MATCH_w_32_0 >> 21 & 0x1f) /* r_06 at 0 */;
      unsigned t_11 = (MATCH_w_32_0 >> 16 & 0x1f) /* t_11 at 0 */;
      nextPC = 4 + MATCH_p; 
      
#line 483 "machine/hppa/decoder.m"
       {

                  // Decode the instruction

                  low_level(RTs, hostPC, pc, result, nextPC);

                  int condvalue;

                  c_c(cmplt, condvalue);

                  if (condvalue != 0)

                      // Anulled. Need to decode the next instruction, and make each

                      // RTAssgn in it conditional on !r[tmpNul]

                      result.type = NCTA;

                  not_used(imm11); not_used(r_06); not_used(t_11);

              } 

      
      
      
    } 
    goto MATCH_finished_d; 
    
  MATCH_label_d2: (void)0; /*placeholder for label*/ 
    { 
      char *name = MATCH_name;
      unsigned c_cmplt = addressToPC(MATCH_p);
      unsigned null_cmplt = addressToPC(MATCH_p);
      unsigned r1 = (MATCH_w_32_0 >> 16 & 0x1f) /* r_11 at 0 */;
      unsigned r2 = (MATCH_w_32_0 >> 21 & 0x1f) /* r_06 at 0 */;
      unsigned target = 
        ((MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */ << 2) + 
        ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 12) + 
        ((sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 
                    1) & 0x7ffff) << 13);
      nextPC = 4 + MATCH_p; 
      
#line 447 "machine/hppa/decoder.m"
       {

                  int condvalue;

                  SemStr* cond_ss = c_c(c_cmplt, condvalue);

                  // Get semantics for the add part (only)

                  RTs = instantiate(pc, name, dis_Reg(r1), dis_Reg(r2));

                  HLJcond* jump = new HLJcond(pc, RTs);

                  jump->setCondType(hl_jcond_type[condvalue]);

                  jump->setDest(dis_Num(target + pc + 8));

                  SemStr* reg1 = dis_Reg(r1);

                  SemStr* reg2 = dis_Reg(r2);

                  reg1->prep(idRegOf);

                  reg2->prep(idRegOf);

                  SemStr* tgt = new SemStr(*reg2);      // Each actual is deleted

                  substituteCallArgs("c_c", cond_ss, reg1, reg2, tgt);

                  jump->setCondExpr(cond_ss);

                  bool isNull = is_null(null_cmplt);

                  // If isNull, then taken forward or failing backwards anull

                  result.type = isNull ? (((int)target >= 0) ? SCDAT : SCDAN) : SCD;

                  result.rtl = jump;

                  result.numBytes = 4;

              }

              // The following two groups of instructions may or may not be anulling

              // (NCTA). If not, let the low level decoder take care of it.

      
      
      
    } 
    goto MATCH_finished_d; 
    
  MATCH_label_d3: (void)0; /*placeholder for label*/ 
    { 
      char *name = MATCH_name;
      unsigned c_cmplt = addressToPC(MATCH_p);
      unsigned im5_11 = 
        ((sign_extend((MATCH_w_32_0 >> 16 & 0x1) /* im1_15 at 0 */, 
                    1) & 0xfffffff) << 4) + 
        (MATCH_w_32_0 >> 17 & 0xf) /* im4_11 at 0 */;
      unsigned null_cmplt = addressToPC(MATCH_p);
      unsigned r_06 = (MATCH_w_32_0 >> 21 & 0x1f) /* r_06 at 0 */;
      unsigned target = 
        ((MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */ << 2) + 
        ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 12) + 
        ((sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 
                    1) & 0x7ffff) << 13);
      nextPC = 4 + MATCH_p; 
      
#line 389 "machine/hppa/decoder.m"
       {

                  int condvalue;

                  SemStr* cond_ss = c_c(c_cmplt, condvalue);

                  // Get semantics for the add part (only)

                  RTs = instantiate(pc, name, dis_Num(im5_11), dis_Reg(r_06));

                  HLJcond* jump = new HLJcond(pc, RTs);

                  jump->setCondType(hl_jcond_type[condvalue]);

                  jump->setDest(dis_Num(target + pc + 8));

                  SemStr* imm = dis_Num(im5_11);

                  SemStr* reg = dis_Reg(r_06);

                  reg->prep(idRegOf);

                  SemStr* tgt = new SemStr(*reg);      // Each actual is deleted

                  substituteCallArgs("c_c", cond_ss, imm, reg, tgt);

                  jump->setCondExpr(cond_ss);

                  bool isNull = is_null(null_cmplt);

                  // If isNull, then taken forward or failing backwards anull

                  result.type = isNull ? (((int)target >= 0) ? SCDAT : SCDAN) : SCD;

                  result.rtl = jump;

                  result.numBytes = 4;

              }

      
      
      
    } 
    goto MATCH_finished_d; 
    
  MATCH_label_d4: (void)0; /*placeholder for label*/ 
    { 
      unsigned bit_cmplt = addressToPC(MATCH_p);
      unsigned c_cmplt = addressToPC(MATCH_p);
      unsigned null_cmplt = addressToPC(MATCH_p);
      unsigned r = (MATCH_w_32_0 >> 16 & 0x1f) /* r_11 at 0 */;
      unsigned target = 
        ((MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */ << 2) + 
        ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 12) + 
        ((sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 
                    1) & 0x7ffff) << 13);
      nextPC = 4 + MATCH_p; 
      
#line 332 "machine/hppa/decoder.m"
       {

                  int condvalue;

                  SemStr* cond_ss = c_c(c_cmplt, condvalue);

                  HLJcond* jump = new HLJcond(pc, RTs);

                  jump->setDest(dis_Num(target + pc + 8));

                  SemStr* reg = dis_Reg(r);

                  SemStr* mask = dis_c_bit(bit_cmplt);

                  SemStr* exp = new SemStr;

                  *exp << idBitAnd << *mask << *reg;

                  substituteCallArgs("c_c", cond_ss, mask, reg, exp);

                  jump->setCondExpr(cond_ss);

                  bool isNull = is_null(null_cmplt);

                  result.type = isNull ? (((int)target >= 0) ? SCDAT : SCDAN) : SCD;

                  result.rtl = jump;

                  result.numBytes = 4;

              }

              

      
      
      
    } 
    goto MATCH_finished_d; 
    
  MATCH_finished_d: (void)0; /*placeholder for label*/
  
}

#line 499 "machine/hppa/decoder.m"
    }
    return result;
}

// Let the low level decoder handle this instruction
void NJMCDecoder::low_level(list<RT*>*& RTs, ADDRESS hostPC, ADDRESS pc,
  DecodeResult& result, ADDRESS& nextPC)
{
    RTs = decodeLowLevelInstruction(hostPC, pc, result);
    if (preInstSem && RTs)
        RTs->insert(RTs->begin(), preInstSem->begin(), preInstSem->end());
    if (postInstSem && RTs)
        RTs->insert(RTs->end(), postInstSem->begin(), postInstSem->end());
    result.rtl = new RTL(pc, RTs);
    nextPC = hostPC + 4;        // 4 byte instruction
    result.numBytes = 4;
}

SemStr* NJMCDecoder::dis_c_bit(ADDRESS hostpc)
{
    SemStr* result;


#line 519 "machine/hppa/decoder.m"
{ 
  dword MATCH_p = 
    
#line 519 "machine/hppa/decoder.m"
    hostpc
    ;
  unsigned MATCH_w_32_0;
  { 
    MATCH_w_32_0 = getDword(MATCH_p); 
    if (0 <= (MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */ && 
      (MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */ < 48) 
      goto MATCH_label_c0;  /*opt-block+*/
    else 
      switch((MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */) {
        case 50: case 51: case 52: case 53: case 54: case 55: case 56: 
        case 57: case 58: case 59: case 60: case 61: case 62: case 63: 
          goto MATCH_label_c0; break;
        case 48: 
          
#line 524 "machine/hppa/decoder.m"
           {

                      result = instantiateNamedParam( "bitpos_sar", dis_Num(0));

                  }

          
          
          
          break;
        case 49: 
          if ((MATCH_w_32_0 >> 13 & 0x1) /* d_18 at 0 */ == 0) { 
            unsigned p = (MATCH_w_32_0 >> 21 & 0x1f) /* p_06 at 0 */;
            
#line 521 "machine/hppa/decoder.m"
             {

                        result = instantiateNamedParam( "bitpos_fix", dis_Num(p));

                    }

            
            
            
          } /*opt-block*//*opt-block+*/
          else 
            goto MATCH_label_c0;  /*opt-block+*/
          
          break;
        default: assert(0);
      } /* (MATCH_w_32_0 >> 26 & 0x3f) -- op at 0 --*/ 
    
  }goto MATCH_finished_c; 
  
  MATCH_label_c0: (void)0; /*placeholder for label*/ 
    assert(0);  /* no match */ 
    goto MATCH_finished_c; 
    
  MATCH_finished_c: (void)0; /*placeholder for label*/
  
}

#line 528 "machine/hppa/decoder.m"
    return result;
}

SemStr* NJMCDecoder::dis_xd(ADDRESS hostpc)
{
    SemStr* result;


#line 533 "machine/hppa/decoder.m"
{ 
  dword MATCH_p = 
    
#line 533 "machine/hppa/decoder.m"
    hostpc
    ;
  unsigned MATCH_w_32_0;
  { 
    MATCH_w_32_0 = getDword(MATCH_p); 
    
      switch((MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */) {
        case 0: case 1: case 2: case 4: case 5: case 6: case 7: case 8: 
        case 10: case 12: case 13: case 14: case 15: case 20: case 21: 
        case 22: case 23: case 28: case 29: case 30: case 31: case 32: 
        case 33: case 34: case 35: case 36: case 37: case 38: case 39: 
        case 40: case 41: case 42: case 43: case 44: case 45: case 46: 
        case 47: case 48: case 49: case 50: case 51: case 52: case 53: 
        case 54: case 55: case 58: case 59: case 60: case 61: case 62: 
        case 63: 
          goto MATCH_label_b0; break;
        case 3: 
          if ((MATCH_w_32_0 >> 12 & 0x1) /* addr_19 at 0 */ == 1) 
            if (8 <= (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ && 
              (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ < 16) { 
              unsigned i = 
                (sign_extend((MATCH_w_32_0 & 0x1) /* i_31 at 0 */, 1) << 4) + 
                (MATCH_w_32_0 >> 1 & 0xf) /* im4_27 at 0 */;
              
#line 553 "machine/hppa/decoder.m"
               {

                          result = instantiateNamedParam( "s_addr_r_im"   , dis_Num(i));

                    }

              
              
              
            } /*opt-block*//*opt-block+*/
            else 
              goto MATCH_label_b4;  /*opt-block+*/ /*opt-block+*/
          else 
            
              switch((MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */) {
                case 0: 
                  if ((MATCH_w_32_0 >> 13 & 0x1) /* u_18 at 0 */ == 1) { 
                    unsigned x = (MATCH_w_32_0 >> 16 & 0x1f) /* x_11 at 0 */;
                    
#line 538 "machine/hppa/decoder.m"
                     {

                                result = instantiateNamedParam( "x_addr_s_byte" , dis_Reg(x));

                          }

                    
                    
                    
                  } /*opt-block*//*opt-block+*/
                  else 
                    goto MATCH_label_b1;  /*opt-block+*/
                  
                  break;
                case 1: 
                  if ((MATCH_w_32_0 >> 13 & 0x1) /* u_18 at 0 */ == 1) { 
                    unsigned x = (MATCH_w_32_0 >> 16 & 0x1f) /* x_11 at 0 */;
                    
#line 541 "machine/hppa/decoder.m"
                     {

                                result = instantiateNamedParam( "x_addr_s_hwrd" , dis_Reg(x));

                          }

                    
                    
                    
                  } /*opt-block*//*opt-block+*/
                  else 
                    goto MATCH_label_b1;  /*opt-block+*/
                  
                  break;
                case 2: case 6: 
                  if ((MATCH_w_32_0 >> 13 & 0x1) /* u_18 at 0 */ == 1) 
                    goto MATCH_label_b2;  /*opt-block+*/
                  else 
                    goto MATCH_label_b1;  /*opt-block+*/
                  
                  break;
                case 3: case 4: case 5: case 7: 
                  if ((MATCH_w_32_0 >> 13 & 0x1) /* u_18 at 0 */ == 1) 
                    goto MATCH_label_b3;  /*opt-block+*/
                  else 
                    goto MATCH_label_b1;  /*opt-block+*/
                  
                  break;
                case 8: case 9: case 10: case 11: case 12: case 13: case 14: 
                case 15: 
                  goto MATCH_label_b0; break;
                default: assert(0);
              } /* (MATCH_w_32_0 >> 6 & 0xf) -- ext4_22 at 0 --*/  
          break;
        case 9: 
          if ((MATCH_w_32_0 >> 7 & 0x3) /* uid2_23 at 0 */ == 0) 
            if ((MATCH_w_32_0 >> 12 & 0x1) /* addr_19 at 0 */ == 1) 
              goto MATCH_label_b4;  /*opt-block+*/
            else 
              if ((MATCH_w_32_0 >> 13 & 0x1) /* u_18 at 0 */ == 1 && 
                (0 <= (MATCH_w_32_0 >> 9 & 0x1) /* addr_22 at 0 */ && 
                (MATCH_w_32_0 >> 9 & 0x1) /* addr_22 at 0 */ < 2)) 
                goto MATCH_label_b2;  /*opt-block+*/
              else 
                goto MATCH_label_b1;  /*opt-block+*/ /*opt-block+*/ 
          else 
            goto MATCH_label_b0;  /*opt-block+*/
          break;
        case 11: 
          if ((MATCH_w_32_0 >> 7 & 0x3) /* uid2_23 at 0 */ == 0) 
            if ((MATCH_w_32_0 >> 12 & 0x1) /* addr_19 at 0 */ == 1) 
              goto MATCH_label_b4;  /*opt-block+*/
            else 
              if ((MATCH_w_32_0 >> 13 & 0x1) /* u_18 at 0 */ == 1 && 
                (0 <= (MATCH_w_32_0 >> 9 & 0x1) /* addr_22 at 0 */ && 
                (MATCH_w_32_0 >> 9 & 0x1) /* addr_22 at 0 */ < 2)) 
                goto MATCH_label_b3;  /*opt-block+*/
              else 
                goto MATCH_label_b1;  /*opt-block+*/ /*opt-block+*/ 
          else 
            goto MATCH_label_b0;  /*opt-block+*/
          break;
        case 16: case 17: case 18: case 19: case 24: case 25: case 26: 
        case 27: 
          { 
            unsigned i = 
              (sign_extend((MATCH_w_32_0 & 0x1) /* i_31 at 0 */, 1) << 13) + 
              (MATCH_w_32_0 >> 1 & 0x1fff) /* im13_18 at 0 */;
            
#line 556 "machine/hppa/decoder.m"
             {

                        result = instantiateNamedParam( "l_addr_16_old" , dis_Num(i));

                  }

            
            
            
          }
          
          break;
        case 56: case 57: 
          { 
            unsigned i = 
              ((MATCH_w_32_0 >> 2 & 0x1) /* w_29 at 0 */ << 10) + 
              ((MATCH_w_32_0 >> 16 & 0x1f) /* w5_11 at 0 */ << 11) + 
              (sign_extend((MATCH_w_32_0 & 0x1) /* w_31 at 0 */, 1) << 16) + 
              (MATCH_w_32_0 >> 3 & 0x3ff) /* w10_19 at 0 */;
            
#line 559 "machine/hppa/decoder.m"
             {

                        result = instantiateNamedParam( "l_addr_17_old" , dis_Num(i));

                  }

            
            
            
          }
          
          break;
        default: assert(0);
      } /* (MATCH_w_32_0 >> 26 & 0x3f) -- op at 0 --*/ 
    
  }goto MATCH_finished_b; 
  
  MATCH_label_b0: (void)0; /*placeholder for label*/ 
    assert(0);  /* no match */ 
    goto MATCH_finished_b; 
    
  MATCH_label_b1: (void)0; /*placeholder for label*/ 
    { 
      unsigned x = (MATCH_w_32_0 >> 16 & 0x1f) /* x_11 at 0 */;
      
#line 535 "machine/hppa/decoder.m"
       {

                  result = instantiateNamedParam( "x_addr_nots"   , dis_Reg(x));

            }

      
      
      
    } 
    goto MATCH_finished_b; 
    
  MATCH_label_b2: (void)0; /*placeholder for label*/ 
    { 
      unsigned x = (MATCH_w_32_0 >> 16 & 0x1f) /* x_11 at 0 */;
      
#line 544 "machine/hppa/decoder.m"
       {

                  result = instantiateNamedParam( "x_addr_s_word" , dis_Reg(x));

            }

      
      
      
    } 
    goto MATCH_finished_b; 
    
  MATCH_label_b3: (void)0; /*placeholder for label*/ 
    { 
      unsigned x = (MATCH_w_32_0 >> 16 & 0x1f) /* x_11 at 0 */;
      
#line 547 "machine/hppa/decoder.m"
       {

                  result = instantiateNamedParam( "x_addr_s_dwrd" , dis_Reg(x));

            }

      
      
      
    } 
    goto MATCH_finished_b; 
    
  MATCH_label_b4: (void)0; /*placeholder for label*/ 
    { 
      unsigned i = 
        (sign_extend((MATCH_w_32_0 >> 16 & 0x1) /* im1_15 at 0 */, 1) << 4) + 
        (MATCH_w_32_0 >> 17 & 0xf) /* im4_11 at 0 */;
      
#line 550 "machine/hppa/decoder.m"
       {

                  result = instantiateNamedParam( "s_addr_im_r"   , dis_Num(i));

            }

      
      
      
    } 
    goto MATCH_finished_b; 
    
  MATCH_finished_b: (void)0; /*placeholder for label*/
  
}

#line 563 "machine/hppa/decoder.m"
    return result;
}

/*==============================================================================
 * FUNCTION:        c_addr
 * OVERVIEW:        Processes completers for various addressing modes
 * NOTE:            I think we need to pass the base register to this function
 * PARAMETERS:      hostpc - the instruction stream address of the dynamic
 *                    address
 *                  ssb - SemStr* for the base register that gets modified
 *                  ssx - SemStr* for the amount to be added to ssb
 * RETURNS:         the SemStr representation of the given address
 *============================================================================*/
SemStr* NJMCDecoder::dis_c_addr(ADDRESS hostPC)
{
    SemStr* result = NULL;


#line 578 "machine/hppa/decoder.m"
{ 
  dword MATCH_p = 
    
#line 578 "machine/hppa/decoder.m"
    hostPC
    ;
  unsigned MATCH_w_32_0;
  { 
    MATCH_w_32_0 = getDword(MATCH_p); 
    if (28 <= (MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */ && 
      (MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */ < 64) 
      goto MATCH_label_a0;  /*opt-block+*/
    else 
      switch((MATCH_w_32_0 >> 26 & 0x3f) /* op at 0 */) {
        case 0: case 1: case 2: case 4: case 5: case 6: case 7: case 8: 
        case 10: case 12: case 13: case 14: case 15: case 20: case 21: 
        case 22: case 23: 
          goto MATCH_label_a0; break;
        case 3: 
          if ((MATCH_w_32_0 >> 12 & 0x1) /* addr_19 at 0 */ == 1) 
            if ((MATCH_w_32_0 >> 5 & 0x1) /* m_26 at 0 */ == 1) 
              if ((MATCH_w_32_0 >> 13 & 0x1) /* a_18 at 0 */ == 1) 
                if (12 <= (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ && 
                  (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ < 14) 
                  
#line 593 "machine/hppa/decoder.m"
                  

                           { result = instantiateNamedParam( "c_y_addr_me" ); }

                  
                   /*opt-block+*/
                else 
                  goto MATCH_label_a5;  /*opt-block+*/ /*opt-block+*/
              else 
                if (12 <= (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ && 
                  (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ < 14) 
                  
#line 591 "machine/hppa/decoder.m"
                  

                           { result = instantiateNamedParam( "c_y_addr_m" ); }

                  
                   /*opt-block+*/
                else 
                  goto MATCH_label_a4;  /*opt-block+*/ /*opt-block+*/ 
            else 
              if (12 <= (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ && 
                (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ < 14) 
                if ((MATCH_w_32_0 >> 13 & 0x1) /* a_18 at 0 */ == 1) 
                  
#line 589 "machine/hppa/decoder.m"
                  

                           { result = instantiateNamedParam( "c_y_addr_e" ); }

                  
                   /*opt-block+*/
                else 
                  
#line 595 "machine/hppa/decoder.m"
                  

                           { result = instantiateNamedParam( "c_y_addr_none" ); }

                  
                   /*opt-block+*/ /*opt-block+*/
              else 
                goto MATCH_label_a3;  /*opt-block+*/  
          else 
            if (0 <= (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ && 
              (MATCH_w_32_0 >> 6 & 0xf) /* ext4_22 at 0 */ < 8) 
              if ((MATCH_w_32_0 >> 5 & 0x1) /* m_26 at 0 */ == 1) 
                goto MATCH_label_a2;  /*opt-block+*/
              else 
                goto MATCH_label_a1;  /*opt-block+*/ /*opt-block+*/
            else 
              goto MATCH_label_a0;  /*opt-block+*/ 
          break;
        case 9: case 11: 
          if ((MATCH_w_32_0 >> 7 & 0x3) /* uid2_23 at 0 */ == 0) 
            if ((MATCH_w_32_0 >> 12 & 0x1) /* addr_19 at 0 */ == 1) 
              if ((MATCH_w_32_0 >> 5 & 0x1) /* m_26 at 0 */ == 1) 
                if ((MATCH_w_32_0 >> 13 & 0x1) /* a_18 at 0 */ == 1 && 
                  (0 <= (MATCH_w_32_0 >> 9 & 0x1) /* addr_22 at 0 */ && 
                  (MATCH_w_32_0 >> 9 & 0x1) /* addr_22 at 0 */ < 2)) 
                  goto MATCH_label_a5;  /*opt-block+*/
                else 
                  goto MATCH_label_a4;  /*opt-block+*/ /*opt-block+*/
              else 
                goto MATCH_label_a3;  /*opt-block+*/ 
            else 
              if ((MATCH_w_32_0 >> 5 & 0x1) /* m_26 at 0 */ == 1 && 
                (0 <= (MATCH_w_32_0 >> 9 & 0x1) /* addr_22 at 0 */ && 
                (MATCH_w_32_0 >> 9 & 0x1) /* addr_22 at 0 */ < 2)) 
                goto MATCH_label_a2;  /*opt-block+*/
              else 
                goto MATCH_label_a1;  /*opt-block+*/ /*opt-block+*/ 
          else 
            goto MATCH_label_a0;  /*opt-block+*/
          break;
        case 16: case 17: case 18: case 19: case 24: case 25: case 26: 
        case 27: 
          
#line 597 "machine/hppa/decoder.m"
          

          		 { result = instantiateNamedParam( "c_l_addr_none" ); }

          
          
          
          break;
        default: assert(0);
      } /* (MATCH_w_32_0 >> 26 & 0x3f) -- op at 0 --*/ 
    
  }goto MATCH_finished_a; 
  
  MATCH_label_a0: (void)0; /*placeholder for label*/ 
    assert(0);  /* no match */ 
    goto MATCH_finished_a; 
    
  MATCH_label_a1: (void)0; /*placeholder for label*/ 
    
#line 587 "machine/hppa/decoder.m"
    

             { result = instantiateNamedParam( "c_x_addr_notm" ); }

    
     
    goto MATCH_finished_a; 
    
  MATCH_label_a2: (void)0; /*placeholder for label*/ 
    
#line 585 "machine/hppa/decoder.m"
    

             { result = instantiateNamedParam( "c_x_addr_m" ); }

    
     
    goto MATCH_finished_a; 
    
  MATCH_label_a3: (void)0; /*placeholder for label*/ 
    
#line 583 "machine/hppa/decoder.m"
    

    	     { result = instantiateNamedParam( "c_s_addr_notm" ); }

    
     
    goto MATCH_finished_a; 
    
  MATCH_label_a4: (void)0; /*placeholder for label*/ 
    
#line 581 "machine/hppa/decoder.m"
    

    	     { result = instantiateNamedParam( "c_s_addr_ma" ); }

    
     
    goto MATCH_finished_a; 
    
  MATCH_label_a5: (void)0; /*placeholder for label*/ 
    
#line 579 "machine/hppa/decoder.m"
    

    		 { result = instantiateNamedParam( "c_s_addr_mb" ); }

    
     
    goto MATCH_finished_a; 
    
  MATCH_finished_a: (void)0; /*placeholder for label*/
  
}

#line 601 "machine/hppa/decoder.m"
    return result;
}

SemStr* NJMCDecoder::dis_c_wcr(unsigned hostPC)
{
    return 0;
}

SemStr* NJMCDecoder::dis_ct(unsigned hostPC)
{
    return 0;
}

SemStr* NJMCDecoder::dis_Freg(int regNum, int fmt)
{
    int r;          // Final register number
    switch (fmt) {
        case 0:     // SGL
            r = regNum + 64;
            break;
        case 1:     // DBL
            r = regNum + 32;
            break;
        case 2:     // QUAD
            r = regNum + 128;
            break;
        default:
            printf("Error decoding floating point register %d with format %d\n",
              regNum, fmt);
            r = 0;
    }
    SemStr* ss = new SemStr;
    *ss << idIntConst << r;
    return ss;
}

SemStr* NJMCDecoder::dis_Creg(int regNum)
{
    SemStr* ss = new SemStr;
    *ss << idIntConst << (regNum + 256);
    return ss;
}

SemStr* NJMCDecoder::dis_Sreg(int regNum)
{
    SemStr* ss = new SemStr;
    *ss << idIntConst << regNum;
    return ss;
}

/*==============================================================================
 * FUNCTION:      isFuncPrologue()
 * OVERVIEW:      Check to see if the instructions at the given offset match
 *                  any callee prologue, i.e. does it look like this offset
 *                  is a pointer to a function?
 * PARAMETERS:    hostPC - pointer to the code in question (native address)
 * RETURNS:       True if a match found
 *============================================================================*/
bool isFuncPrologue(ADDRESS hostPC)
{
#if 0
    int hiVal, loVal, reg, locals;
    if ((InstructionPatterns::new_reg_win(prog.csrSrc,hostPC, locals)) != NULL)
            return true;
    if ((InstructionPatterns::new_reg_win_large(prog.csrSrc, hostPC,
        hiVal, loVal, reg)) != NULL)
            return true;
    if ((InstructionPatterns::same_reg_win(prog.csrSrc, hostPC, locals))
        != NULL)
            return true;
    if ((InstructionPatterns::same_reg_win_large(prog.csrSrc, hostPC,
        hiVal, loVal, reg)) != NULL)
            return true;
#endif

    return false;
}



