Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Decode.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: SS_Decode.h
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
*
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ========== Copyright Header End ============================================
*/
#ifndef __SS_Decode_h__
#define __SS_Decode_h__
#include "SS_Opcode.h"
#include "SS_Instr.h"
#include "SS_Strand.h"
// SS_DecodeGroup<SIZE> holds a group of instructions that need further
// decoding after the {op:op3} decoding. The sft and msk specify the
// left shift and mask to apply to the opcode to get a byte index into
// the table tbl of further decode functions.
template<int SIZE> class SS_DecodeGroup
{
public:
uint16_t sft;
uint16_t msk;
SS_Decode tbl[SIZE];
SS_Decode decode( SS_Opcode o )
{
// The number of entries in a decode group must be a power of two.
assert(SIZE & (SIZE - 1) == 0);
return *(SS_Decode*)((char*)tbl + ((uint64_t(o.get()) >> sft) & msk));
}
};
// SS_Decoder is the top level decoder. It takes {op:op3} as the first
// selection into a table of decode functions or decode tables
// The SS_DecodeTable class provides the structure to decode
// instructions. It roots the decode tree. Each level of the decode
// tree contains both SS_Decode entries, which point to methods to
// decode instructions and SS_DecodeGroup template entries, which
// reference the next level in the decode tree.
//
// To distinguish between the two kinds of entries, the LSB of a
// SS_DecodeGroup template address is set to 1. See ss_dec_tbl() and
// dec_grp() below.
#define ss_dec_tbl(p) (SS_Decode)((long)&p + 1)
class SS_DecodeTable
{
public:
SS_Decode decode( SS_Opcode o )
{
SS_Decode d = *(SS_Decode*)((char*)table + ((o.get() >> ptr_sft(30 - 6)) & ptr_msk(3 << 6))
+ ((o.get() >> ptr_sft(19)) & ptr_msk(0x3f)));
if (dec_grp(d))
{
d = tbl_ptr(d)->decode(o);
if (dec_grp(d))
{
d = tbl_ptr(d)->decode(o);
}
}
return d;
}
template<int SIZE>
void set( uint_t i, SS_DecodeGroup<SIZE>* d ) { assert(i<256); table[i] = dec_tbl(d); }
void set( uint_t i, SS_Decode d ) { assert(i<256); table[i] = d; }
SS_Decode table[256]; // Top level decode table for {op:op3}
// dec_grp() returns true when p is a pointer to a SS_DecodeGroup
bool dec_grp( SS_Decode p )
{
return (long)p & 1;
}
// dec_tlb() casts and tags a SS_DecodeGroup pointer into a SS_Decode pointer
template<int SIZE> SS_Decode dec_tbl( SS_DecodeGroup<SIZE>* p )
{
return (SS_Decode)((long)p + 1);
}
// tbl_ptr() casts and untags a SS_Decode pointer into a SS_DecodeGroup pointer
SS_DecodeGroup<1>* tbl_ptr( SS_Decode p )
{
return (SS_DecodeGroup<1>*)((long)p - 1);
}
};
#endif