@@ -2600,12 +2600,14 @@ else if (bci == bCifle)
2600
2600
}
2601
2601
}
2602
2602
2603
+ // checks if a value can be packed into ARM's 12 bit packed format
2603
2604
private boolean isPackable (int val ) {
2604
2605
int lead = Integer .numberOfLeadingZeros (val );
2605
2606
lead -= lead % 2 ; // make even, immediate operands can be shifted by an even number only
2606
2607
return lead + Integer .numberOfTrailingZeros (val ) >= 24 ;
2607
2608
}
2608
2609
2610
+ // packs a value into ARM's 12 bit packed format
2609
2611
private int packImmediate (int immVal ) {
2610
2612
int val = Integer .numberOfLeadingZeros (immVal );
2611
2613
val -= val % 2 ; // make even
@@ -3202,12 +3204,30 @@ private void createBranchReg(Code32 code, int op, int cond, int Rm) {
3202
3204
3203
3205
// load/store word and unsigned byte (immediate) (LDR, LDRB, STR, STRB, LDRH, LDRSH, LDRSB, STRH)
3204
3206
// P = 1 -> preindexed, U = 1 -> add offset, W = 1 -> write back
3205
- private void createLSWordImm (Code32 code , int opCode , int cond , int Rt , int Rn , int imm12 , int P , int U , int W ) {
3206
- if (opCode == armLdr || opCode == armLdrb || opCode == armStr || opCode == armStrb )
3207
- code .instructions [code .iCount ] = (cond << 28 ) | opCode | (Rt << 12 ) | (Rn << 16 ) | (imm12 << 0 ) | (P << 24 ) | (U << 23 ) | (W << 21 );
3208
- else // extra load / store
3209
- code .instructions [code .iCount ] = (cond << 28 ) | opCode | (Rt << 12 ) | (Rn << 16 ) | ((imm12 & 0xf0 ) << 4 ) | (imm12 & 0xf ) | (P << 24 ) | (U << 23 ) | (W << 21 ) | (1 << 22 );
3210
- code .incInstructionNum ();
3207
+ private void createLSWordImm (Code32 code , int opCode , int cond , int Rt , int Rn , int imm , int P , int U , int W ) {
3208
+ switch (opCode ) {
3209
+ case armLdr : case armLdrb : case armStr : case armStrb :
3210
+ if (imm > 0xfff ) ErrorReporter .reporter .error (651 );
3211
+ code .instructions [code .iCount ] = (cond << 28 ) | opCode | (Rt << 12 ) | (Rn << 16 ) | (imm << 0 ) | (P << 24 ) | (U << 23 ) | (W << 21 );
3212
+ code .incInstructionNum ();
3213
+ break ;
3214
+ case armLdrsb : case armLdrsh : case armLdrh : case armStrh : // extra load / store
3215
+ if (imm > 0xff ) {
3216
+ if (imm > 0xfff ) ErrorReporter .reporter .error (651 );
3217
+ int baseOffset = imm / 256 ;
3218
+ int off = imm % 256 ;
3219
+ createDataProcImm (code , armAdd , cond , Rn , Rn , packImmediate (baseOffset * 256 ));
3220
+ code .instructions [code .iCount ] = (cond << 28 ) | opCode | (Rt << 12 ) | (Rn << 16 ) | ((off & 0xf0 ) << 4 ) | (off & 0xf ) | (P << 24 ) | (U << 23 ) | (W << 21 ) | (1 << 22 );
3221
+ code .incInstructionNum ();
3222
+ createDataProcImm (code , armSub , cond , Rn , Rn , packImmediate (baseOffset * 256 ));
3223
+ } else {
3224
+ code .instructions [code .iCount ] = (cond << 28 ) | opCode | (Rt << 12 ) | (Rn << 16 ) | ((imm & 0xf0 ) << 4 ) | (imm & 0xf ) | (P << 24 ) | (U << 23 ) | (W << 21 ) | (1 << 22 );
3225
+ code .incInstructionNum ();
3226
+ }
3227
+ break ;
3228
+ default :
3229
+ ErrorReporter .reporter .error (652 );
3230
+ }
3211
3231
}
3212
3232
3213
3233
// ...(LDR, LDRB : (literal))
@@ -3333,6 +3353,7 @@ private void createFPdataProcImm(Code32 code, int opCode, int cond, int Vd, int
3333
3353
code .incInstructionNum ();
3334
3354
}
3335
3355
3356
+ // creates a pattern within the instruction stream, used for exception epilogue
3336
3357
private void createIpat (Code32 code , int pat ) {
3337
3358
code .instructions [code .iCount ] = pat ;
3338
3359
code .incInstructionNum ();
0 commit comments