3535import com .ibm .j9ddr .StructureReader ;
3636import com .ibm .j9ddr .util .RuntimeTypeResolutionUtils ;
3737import com .ibm .j9ddr .vm29 .j9 .DataType ;
38+ import com .ibm .j9ddr .vm29 .types .I8 ;
39+ import com .ibm .j9ddr .vm29 .types .I16 ;
3840import com .ibm .j9ddr .vm29 .types .I32 ;
41+ import com .ibm .j9ddr .vm29 .types .I64 ;
3942import com .ibm .j9ddr .vm29 .types .Scalar ;
43+ import com .ibm .j9ddr .vm29 .types .U8 ;
44+ import com .ibm .j9ddr .vm29 .types .U16 ;
4045import com .ibm .j9ddr .vm29 .types .U32 ;
46+ import com .ibm .j9ddr .vm29 .types .U64 ;
4147
4248/**
4349 * Root of the hierarchy for VM C structures.
@@ -58,33 +64,101 @@ public DataType at(Scalar count) {
5864 throw new UnsupportedOperationException ("StructurePointers are implicitly dereferenced. Use add(Scalar count) instead." );
5965 }
6066
61- protected int getStartingBit (int s , int b ) {
67+ protected final I8 getI8Bitfield (int bitOffset , int bitWidth ) throws CorruptDataException {
68+ long cellOffset = getCellOffset (bitOffset , 8 );
69+ long cell = getByteAtOffset (cellOffset );
70+ long field = getBitfield (cell , bitOffset , bitWidth , 8 , true );
71+
72+ return new I8 (field );
73+ }
74+
75+ protected final I16 getI16Bitfield (int bitOffset , int bitWidth ) throws CorruptDataException {
76+ long cellOffset = getCellOffset (bitOffset , 16 );
77+ long cell = getShortAtOffset (cellOffset );
78+ long field = getBitfield (cell , bitOffset , bitWidth , 16 , true );
79+
80+ return new I16 (field );
81+ }
82+
83+ protected final I32 getI32Bitfield (int bitOffset , int bitWidth ) throws CorruptDataException {
84+ long cellOffset = getCellOffset (bitOffset , 32 );
85+ long cell = getIntAtOffset (cellOffset );
86+ long field = getBitfield (cell , bitOffset , bitWidth , 32 , true );
87+
88+ return new I32 (field );
89+ }
90+
91+ protected final I64 getI64Bitfield (int bitOffset , int bitWidth ) throws CorruptDataException {
92+ long cellOffset = getCellOffset (bitOffset , 64 );
93+ long cell = getLongAtOffset (cellOffset );
94+ long field = getBitfield (cell , bitOffset , bitWidth , 64 , true );
95+
96+ return new I64 (field );
97+ }
98+
99+ protected final U8 getU8Bitfield (int bitOffset , int bitWidth ) throws CorruptDataException {
100+ long cellOffset = getCellOffset (bitOffset , 8 );
101+ long cell = getByteAtOffset (cellOffset );
102+ long field = getBitfield (cell , bitOffset , bitWidth , 8 , false );
103+
104+ return new U8 (field );
105+ }
106+
107+ protected final U16 getU16Bitfield (int bitOffset , int bitWidth ) throws CorruptDataException {
108+ long cellOffset = getCellOffset (bitOffset , 16 );
109+ long cell = getShortAtOffset (cellOffset );
110+ long field = getBitfield (cell , bitOffset , bitWidth , 16 , false );
111+
112+ return new U16 (field );
113+ }
114+
115+ protected final U32 getU32Bitfield (int bitOffset , int bitWidth ) throws CorruptDataException {
116+ long cellOffset = getCellOffset (bitOffset , 32 );
117+ long cell = getIntAtOffset (cellOffset );
118+ long field = getBitfield (cell , bitOffset , bitWidth , 32 , false );
119+
120+ return new U32 (field );
121+ }
122+
123+ protected final U64 getU64Bitfield (int bitOffset , int bitWidth ) throws CorruptDataException {
124+ long cellOffset = getCellOffset (bitOffset , 64 );
125+ long cell = getLongAtOffset (cellOffset );
126+ long field = getBitfield (cell , bitOffset , bitWidth , 64 , false );
127+
128+ return new U64 (field );
129+ }
130+
131+ private static long getCellOffset (int bitOffset , int cellSize ) {
132+ long cellIndex = bitOffset / cellSize ;
133+
134+ return cellIndex * (cellSize / Byte .SIZE );
135+ }
136+
137+ private static long getBitfield (long cell , int bitOffset , int bitWidth , int cellSize , boolean isSigned ) {
138+ int leftShift ;
139+
62140 switch (BITFIELD_FORMAT ) {
63141 case StructureReader .BIT_FIELD_FORMAT_LITTLE_ENDIAN :
64- return b + (s % StructureReader .BIT_FIELD_CELL_SIZE );
142+ leftShift = Long .SIZE - bitWidth - (bitOffset % cellSize );
143+ break ;
65144 case StructureReader .BIT_FIELD_FORMAT_BIG_ENDIAN :
66- return 32 - (s % StructureReader .BIT_FIELD_CELL_SIZE );
145+ leftShift = Long .SIZE - cellSize + (bitOffset % cellSize );
146+ break ;
67147 default :
68148 throw new IllegalArgumentException ("Unsupported bitfield format" );
69149 }
70- }
71150
72- protected U32 getU32Bitfield (int s , int b ) throws CorruptDataException {
73- int cell = s /StructureReader .BIT_FIELD_CELL_SIZE ;
74- U32 cellValue = new U32 (getIntAtOffset (cell * StructureReader .BIT_FIELD_CELL_SIZE / 8 ));
75- int n = getStartingBit (s , b );
76- U32 returnValue = cellValue .leftShift (StructureReader .BIT_FIELD_CELL_SIZE - n );
77- returnValue = returnValue .rightShift (StructureReader .BIT_FIELD_CELL_SIZE - b );
78- return returnValue ;
79- }
151+ // Shift left so the most significant bit becomes the sign bit.
152+ long leftAligned = cell << leftShift ;
80153
81- protected I32 getI32Bitfield (int s , int b ) throws CorruptDataException {
82- int cell = s /StructureReader .BIT_FIELD_CELL_SIZE ;
83- I32 cellValue = new I32 (getIntAtOffset (cell * StructureReader .BIT_FIELD_CELL_SIZE / 8 ));
84- int n = getStartingBit (s , b );
85- I32 returnValue = cellValue .leftShift (StructureReader .BIT_FIELD_CELL_SIZE - n );
86- returnValue = returnValue .rightShift (StructureReader .BIT_FIELD_CELL_SIZE - b );
87- return returnValue ;
154+ // The number of uninteresting bits in leftAligned.
155+ int rightShift = Long .SIZE - bitWidth ;
156+
157+ if (isSigned ) {
158+ return leftAligned >> rightShift ;
159+ } else {
160+ return leftAligned >>> rightShift ;
161+ }
88162 }
89163
90164 public StructurePointer getAsRuntimeType ()
0 commit comments