Skip to content

Commit f381006

Browse files
committed
Refactor ARM halfword transfer
1 parent b48cd4a commit f381006

File tree

1 file changed

+16
-30
lines changed

1 file changed

+16
-30
lines changed

src/arm.c

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -265,32 +265,36 @@ int __zero(int rd)
265265
return __mov_i(__AL, rd, 0);
266266
}
267267

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+
*/
268274
int arm_halfword_transfer(arm_cond_t cond,
269275
int l,
270276
arm_reg rn,
271277
arm_reg rd,
272-
int ofs)
278+
int ofs,
279+
int signed_op)
273280
{
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-
*/
277281
int opcode = 16 + 8 + 4 + l;
278282

279283
if (ofs < 0) {
280284
opcode -= 8;
281285
ofs = -ofs;
282286
}
283287

284-
/* Halfword encoding: split offset into 4-bit high and low parts */
285288
if (ofs > 255) {
286289
error("Halfword offset too large");
287290
}
288291

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;
290294
int imm4L = ofs & 0xF;
291295

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);
294298

295299
return arm_encode(cond, opcode, rn, rd, encoded_ofs);
296300
}
@@ -332,34 +336,16 @@ int __sb(arm_cond_t cond, arm_reg rd, arm_reg rn, int ofs)
332336
return arm_transfer(cond, 0, 1, rn, rd, ofs);
333337
}
334338

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) */
340340
int __lh(arm_cond_t cond, arm_reg rd, arm_reg rn, int ofs)
341341
{
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);
358343
}
359344

345+
/* ARM halfword store (STRH) */
360346
int __sh(arm_cond_t cond, arm_reg rd, arm_reg rn, int ofs)
361347
{
362-
return arm_halfword_transfer(cond, 0, rn, rd, ofs);
348+
return arm_halfword_transfer(cond, 0, rn, rd, ofs, 0);
363349
}
364350

365351
int __stmdb(arm_cond_t cond, int w, arm_reg rn, int reg_list)

0 commit comments

Comments
 (0)