@@ -265,32 +265,36 @@ int __zero(int rd)
265
265
return __mov_i (__AL , rd , 0 );
266
266
}
267
267
268
+ /* ARM halfword transfer (immediate offset) using special encoding
269
+ * For halfword: bits[11:8] = imm4H, bits[7:4] = encoding, bits[3:0] = imm4L
270
+ * imm4H: upper 4 bits of offset
271
+ * imm4L: lower 4 bits of offset
272
+ * encoding: 0b1011 for unsigned halfword, 0b1111 for signed halfword
273
+ */
268
274
int arm_halfword_transfer (arm_cond_t cond ,
269
275
int l ,
270
276
arm_reg rn ,
271
277
arm_reg rd ,
272
- int ofs )
278
+ int ofs ,
279
+ int signed_op )
273
280
{
274
- /* ARM halfword transfer using special encoding
275
- * For halfword: bits[11:8] = imm4H, bits[3:0] = imm4L, bits[7,6,5,4] = 1SH1
276
- */
277
281
int opcode = 16 + 8 + 4 + l ;
278
282
279
283
if (ofs < 0 ) {
280
284
opcode -= 8 ;
281
285
ofs = - ofs ;
282
286
}
283
287
284
- /* Halfword encoding: split offset into 4-bit high and low parts */
285
288
if (ofs > 255 ) {
286
289
error ("Halfword offset too large" );
287
290
}
288
291
289
- int imm4H = (ofs >> 4 ) & 0xF ;
292
+ /* Halfword encoding: split offset into 4-bit high and low parts */
293
+ int imm4H = ((ofs >> 4 ) & 0xF ) << 8 ;
290
294
int imm4L = ofs & 0xF ;
291
295
292
- /* Encode with S=0, H=1 bits in lower 8 bits: 1011xxxx */
293
- int encoded_ofs = ( imm4H << 8 ) | 0xB0 | imm4L ;
296
+ /* Encode lower 8 bits: 1011xxxx for unsigned, 1111xxxx for signed */
297
+ int encoded_ofs = imm4H | 0xB0 | imm4L | ( signed_op << 6 ) ;
294
298
295
299
return arm_encode (cond , opcode , rn , rd , encoded_ofs );
296
300
}
@@ -332,34 +336,16 @@ int __sb(arm_cond_t cond, arm_reg rd, arm_reg rn, int ofs)
332
336
return arm_transfer (cond , 0 , 1 , rn , rd , ofs );
333
337
}
334
338
335
- int __luh (arm_cond_t cond , arm_reg rd , arm_reg rn , int ofs )
336
- {
337
- return arm_halfword_transfer (cond , 1 , rn , rd , ofs );
338
- }
339
-
339
+ /* ARM signed halfword load (LDRSH) */
340
340
int __lh (arm_cond_t cond , arm_reg rd , arm_reg rn , int ofs )
341
341
{
342
- /* ARM signed halfword load (LDRSH) */
343
- int opcode = 16 + 8 + 4 + 1 ;
344
- if (ofs < 0 ) {
345
- opcode -= 8 ;
346
- ofs = - ofs ;
347
- }
348
-
349
- /* Halfword encoding: split offset into 4-bit high and low parts */
350
- if (ofs > 255 ) {
351
- fatal ("Halfword offset too large" );
352
- }
353
- int imm4H = (ofs >> 4 ) & 0xF ;
354
- int imm4L = ofs & 0xF ;
355
-
356
- int encoded_ofs = (imm4H << 8 ) | 0xF0 | imm4L ;
357
- return arm_encode (cond , opcode , rn , rd , encoded_ofs );
342
+ return arm_halfword_transfer (cond , 1 , rn , rd , ofs , 1 );
358
343
}
359
344
345
+ /* ARM halfword store (STRH) */
360
346
int __sh (arm_cond_t cond , arm_reg rd , arm_reg rn , int ofs )
361
347
{
362
- return arm_halfword_transfer (cond , 0 , rn , rd , ofs );
348
+ return arm_halfword_transfer (cond , 0 , rn , rd , ofs , 0 );
363
349
}
364
350
365
351
int __stmdb (arm_cond_t cond , int w , arm_reg rn , int reg_list )
0 commit comments