Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Instr.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_Instr.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23#ifndef __SS_Instr_h__
24#define __SS_Instr_h__
25
26#include "SS_Types.h"
27#include "SS_Opcode.h"
28#include "SS_Tte.h"
29#include "SS_Chain.h"
30
31class SS_Strand;
32class SS_BreakPoint;
33
34#undef REG_ASI
35
36// The SS_Instr class captures the decoding of an intruction. The
37// decode cache, after decoding, contains SS_Instr objects.
38
39// Danger, danger, danger!!
40//
41// NB: The SS_Instr objects are interwoven in the decode cache and
42// overlap each other. An SS_Instr object's data layout is:
43//
44// Size Content
45// ---- ------
46// 16 bytes Data block 0
47// 15*16 bytes Unused hole
48// 16 bytes Data block 1
49// 15*16 bytes Unused hole
50// 16 bytes Data block 2
51// 15*16 bytes Unused hole
52// 16 bytes Data block 3
53// 15*16 bytes Unused hole
54//
55// For a total size of 1024 bytes, only 1/16 of which hold meaningful
56// data.
57//
58// In the decode cache, 16 SS_Instr objects are overlapped at
59// intervals of 16 bytes. The key advantage is to share a D-cache
60// line among the "data block 0" areas of two SS_Instr objects. Since
61// D-cache lines are typically 32 bytes, this packing eliminates
62// almost D-cache misses for the second "data block 0" of the two
63// SS_Instr object sharing the cache line, at least in the case of
64// sequential execution.
65//
66// Do not modify this class without considering these packing
67// constraints. As a wise girl once said, "You *can* touch this --
68// with your eyes."
69
70
71class SS_Instr
72{
73 public:
74 enum
75 {
76 BITS = 6,
77 SIZE = (1 << BITS),
78
79 SKEW = 2,
80
81 LINE_BITS = 4,
82 LINE_SIZE = 1 << LINE_BITS,
83 LINE_MASK = LINE_SIZE - 1,
84
85 HOLE = (LINE_SIZE - 1) * (1 << (BITS - SKEW)) / sizeof(uint64_t)
86 };
87
88 SS_Instr* line_index( uint_t n )
89 {
90 return (SS_Instr*)((char*)this + (n << (BITS - SKEW)));
91 }
92
93 SS_Instr() { assert(HOLE == 30); }
94
95 union
96 {
97 SS_Execute exe; // The decode or execute routine ...
98 uint64_t align0; // 64bit alignment in v8plus mode
99 };
100
101 // Todo: AsiFlag and LsuFlag use 8 bits all together.
102 // The asi flags don;t serve real meaning anymore as
103 // each have thier own execute (so REG_ASI is known
104 // without looking at this flag. I think we should use
105 //
106 // 000 NON_LSU
107 // 001 READ
108 // 010 WRITE
109 // 011 ATOMIC
110 // 101 FETCH
111 // 110 FLUSH
112 // 110 -
113 // 111 -
114
115 enum AsiFlag
116 {
117 NON_LSU = 0x00, // All non LSU instructions
118 DFT_ASI = 0x01,
119 REG_ASI = 0x02,
120 IMM_ASI = 0x04
121 };
122
123 enum LsuFlag
124 {
125 READ = 0x10,
126 WRITE = 0x20,
127 FETCH = 0x40,
128 FLUSH = 0x80
129 };
130
131 int is_lsu() { return flg != NON_LSU; }
132 int is_dft_asi() { return flg & DFT_ASI; }
133 int is_reg_asi() { return flg & REG_ASI; }
134 int is_imm_asi() { return flg & IMM_ASI; }
135
136 int is_read() { return flg & READ; }
137 int is_write() { return flg & WRITE; }
138 int is_atomic() { return (flg & (READ|WRITE)) == (READ|WRITE); }
139
140 int is_fetch() { return flg & FETCH; }
141 int is_flush() { return flg & FLUSH; }
142 int is_cohere() { return flg & (FETCH|FLUSH); }
143
144 // All register values below (rd, rs1, rd2, rs3) are not the
145 // register number mapping directly to %g3, %l5, etc. Instead,
146 // they are the ***byte offset*** into the Strand's integer
147 // register file. So instruction referencing %g2 as its rd would
148 // store 16 in "rd" below because registers are 8 bytes in size.
149
150 int16_t rd;
151 int16_t rs1;
152 int16_t rs2; // Index to rs2 or signed immediate value
153 union
154 {
155 int16_t rs3; // Index to rs3
156 uint16_t asi; // The asi used by LSU instructions (dft/reg/imm) @@ha144505 Todo -> uint8!
157 };
158
159 uint64_t stride0[HOLE]; // For overlapping 16 SS_Instr in the decode cache
160
161 SS_Opcode opc;
162 uint8_t flg; // Flags specifing memory operation type
163 uint8_t len; // The size of the memory operation
164 uint16_t spare0;
165
166 union
167 {
168 SS_Tte* tte; // Data TTE for LSU instructions. Bit0 is endianess, Bit1 is MEM(0)/IO(1)
169 SS_BreakPoint* bp; // Pointer to breakpoint set on this instruction
170 };
171
172 uint64_t stride1[HOLE]; // For overlapping 16 SS_Instr in the decode cache
173
174 SS_Chain lnk; // Link same TTE together
175
176 //uint64_t stride2[HOLE]; // For overlapping 16 SS_Instr in the decode cache
177 SS_Chain stride2[LINE_SIZE-1];
178
179 uint16_t exe_tbl_idx; // Index into exe_table for this instruction
180
181 uint16_t spare1; // Reserved space
182 uint32_t spare2;
183 uint64_t spare3;
184
185 uint64_t stride3[HOLE]; // For overlapping 16 SS_Instr in the decode cache
186
187 SS_Tte* get_tte() { return (SS_Tte*)(long(tte) &~ long(3)); }
188 int tte_le() { return long(tte) & 1; }
189 int tte_io() { return long(tte) & 2; }
190 int tte_le_io() { return long(tte) & 3; }
191
192 SS_Tte* set_tte( uint_t le, uint_t io, SS_Tte* t )
193 {
194 assert((le == 0) || (le == 1));
195 assert((io == 0) || (io == 2));
196 tte = (SS_Tte*)(long(t) + long(le) + long(io));
197 return tte;
198 }
199
200
201};
202
203#endif
204