Skip to content

Commit 3fa3c2c

Browse files
target/arc: implement {push,pop}dl_s instructions
This commit provides support for the translation of push/pop double instructions (a.k.a. pushdl_s and popdl_s) by decomposing them into two 8-byte writes and adjusting the stack pointer as necessary. Changes to the decoder, while unnecessary, are made to reflect those to the opcodes directory in the binutils-gdb repository. Signed-off-by: Artemiy Volkov <[email protected]>
1 parent e32cf88 commit 3fa3c2c

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

target/arc/decoder_fragments/arc64-tbl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6587,7 +6587,7 @@
65876587
{ "pop_s", 0x0000C0D1, 0x0000F8FF, ARC_OPCODE_ARC32, POP, NONE, { BLINK_S }, { C_AA_AB }},
65886588

65896589
/* popdl_s RBB_S 11000xxx1101xxx1 */
6590-
{ "popdl_s", 0x0000c0d1, 0x0000f8f1, ARC_OPCODE_ARC64, ARITH, NONE, { RBB_S }, { 0 } }
6590+
{ "popdl_s", 0x0000c0d1, 0x0000f8f1, ARC_OPCODE_ARC64, ARITH, NONE, { RBB_S_CHK }, { 0 } }
65916591

65926592
/* popl_s RBB_S 11000xxx1100xxx1 */
65936593
{ "popl_s", 0x0000c0c1, 0x0000f8f1, ARC_OPCODE_ARC64, ARITH, NONE, { RBB_S }, { 0 } }
@@ -6653,7 +6653,7 @@
66536653
{ "push_s", 0x0000C0F1, 0x0000F8FF, ARC_OPCODE_ARC32, PUSH, NONE, { BLINK_S }, { C_AA_AW }},
66546654

66556655
/* pushdl_s RBB_S 11000xxx1111xxx1 */
6656-
{ "pushdl_s", 0x0000c0f1, 0x0000f8f1, ARC_OPCODE_ARC64, ARITH, NONE, { RBB_S }, { 0 } }
6656+
{ "pushdl_s", 0x0000c0f1, 0x0000f8f1, ARC_OPCODE_ARC64, ARITH, NONE, { RBB_S_CHK }, { 0 } }
66576657

66586658
/* pushl_s RBB_S 11000xxx1110xxx1 */
66596659
{ "pushl_s", 0x0000c0e1, 0x0000f8f1, ARC_OPCODE_ARC64, ARITH, NONE, { RBB_S }, { 0 } }

target/arc/operands.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ ARC_OPERAND(RA_CHK, 6, 0, 0, ARC_OPERAND_IR, 0)
2222
ARC_OPERAND(RB, 6, 12, 0, ARC_OPERAND_IR, extract_rb)
2323
ARC_OPERAND(RB_CHK, 6, 12, 0, ARC_OPERAND_IR, extract_rb)
2424
ARC_OPERAND(RBB_S, 6, 12, 0, ARC_OPERAND_IR, extract_rbb)
25+
ARC_OPERAND(RBB_S_CHK, 6, 12, 0, ARC_OPERAND_IR, extract_rbb)
2526
ARC_OPERAND(RC, 6, 6, 0, ARC_OPERAND_IR, 0)
2627
ARC_OPERAND(RC_CHK, 6, 6, 0, ARC_OPERAND_IR, 0)
2728
ARC_OPERAND(RBdup, 6, 12, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, extract_rb)

target/arc/semfunc-mapping.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,12 +402,14 @@ SEMANTIC_FUNCTION(SCONDL, 2)
402402
SEMANTIC_FUNCTION(LDL, 3)
403403
SEMANTIC_FUNCTION(STL, 3)
404404
SEMANTIC_FUNCTION(POPL, 1)
405+
SEMANTIC_FUNCTION(POPDL, 1)
405406
SEMANTIC_FUNCTION(NORML, 2)
406407
SEMANTIC_FUNCTION(FLSL, 2)
407408
SEMANTIC_FUNCTION(FFSL, 2)
408409
SEMANTIC_FUNCTION(DBNZL, 2)
409410
SEMANTIC_FUNCTION(SEXWL, 2)
410411
SEMANTIC_FUNCTION(PUSHL, 1)
412+
SEMANTIC_FUNCTION(PUSHDL, 1)
411413
SEMANTIC_FUNCTION(BBIT0L, 3)
412414
SEMANTIC_FUNCTION(BBIT1L, 3)
413415

@@ -509,9 +511,9 @@ MAPPING(tstl, TSTL, 2, 0, 1)
509511
MAPPING(xbful, XBFUL, 3, 2, 1, 0)
510512

511513
MAPPING(pushl_s, PUSHL, 1, 0)
512-
MAPPING(pushdl_s, PUSHL, 1, 0)
514+
MAPPING(pushdl_s, PUSHDL, 1, 0)
513515
MAPPING(popl_s, POPL, 1, 0)
514-
MAPPING(popdl_s, POPL, 1, 0)
516+
MAPPING(popdl_s, POPDL, 1, 0)
515517

516518
MAPPING(bbit0l, BBIT0L, 3, 0, 1, 2)
517519
MAPPING(bbit1l, BBIT1L, 3, 0, 1, 2)

target/arc/semfunc-v3.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12022,6 +12022,40 @@ arc_gen_POPL(DisasCtxt *ctx, TCGv dest)
1202212022

1202312023

1202412024

12025+
/* POPDL
12026+
* Given an even-numbered register @src, read the 128-bit value at $sp into
12027+
* @src (low part) and @src+1 (high part), then increment $sp by 16 bytes. As
12028+
* confirmed using nsim, since ARCv3 is little-endian, the low part should be
12029+
* popped first. The hardware performs not a single 16-byte operation, but
12030+
* rather two consecutive 8-byte operations.
12031+
*
12032+
* No flags are affected by this instruction.
12033+
*/
12034+
12035+
int
12036+
arc_gen_POPDL(DisasCtxt *ctx, TCGv dest)
12037+
{
12038+
TCGv sp = tcg_temp_new();
12039+
TCGv next_reg = nextReg(dest);
12040+
12041+
tcg_gen_mov_tl(sp, cpu_sp);
12042+
12043+
tcg_gen_qemu_ld_tl(dest, sp, ctx->mem_idx, MO_UQ);
12044+
tcg_gen_addi_tl(sp, sp, 8);
12045+
12046+
tcg_gen_qemu_ld_tl(next_reg, sp, ctx->mem_idx, MO_UQ);
12047+
tcg_gen_addi_tl(sp, sp, 8);
12048+
12049+
if (dest != cpu_sp) {
12050+
tcg_gen_mov_tl(cpu_sp, sp);
12051+
}
12052+
12053+
tcg_temp_free(sp);
12054+
12055+
return DISAS_NEXT;
12056+
}
12057+
12058+
1202512059

1202612060

1202712061
/* PUSHL
@@ -12050,6 +12084,38 @@ arc_gen_PUSHL(DisasCtxt *ctx, TCGv src)
1205012084

1205112085

1205212086

12087+
/* PUSHDL
12088+
* Given an even-numbered register @src, decrement $sp by 16 bytes, then write
12089+
* the 128-bit value represented by @src (low part) and @src+1 (high part) into
12090+
* the memory at $sp-16. As confirmed using nsim, since ARCv3 is little-endian,
12091+
* the high part should be pushed first. The hardware performs not a single
12092+
* 16-byte operation, but two consecutive 8-byte operations.
12093+
*
12094+
* No flags are affected by this instruction.
12095+
*/
12096+
12097+
int
12098+
arc_gen_PUSHDL(DisasCtxt *ctx, TCGv src)
12099+
{
12100+
TCGv sp = tcg_temp_new();
12101+
TCGv next_reg = nextReg(src);
12102+
12103+
tcg_gen_mov_tl(sp, cpu_sp);
12104+
tcg_gen_subi_tl(sp, sp, 16);
12105+
tcg_gen_qemu_st_tl(src, sp, ctx->mem_idx, MO_UQ);
12106+
12107+
tcg_gen_addi_tl(sp, sp, 8);
12108+
tcg_gen_qemu_st_tl(next_reg, sp, ctx->mem_idx, MO_UQ);
12109+
12110+
tcg_gen_subi_tl(cpu_sp, sp, 8);
12111+
12112+
tcg_temp_free(sp);
12113+
12114+
return DISAS_NEXT;
12115+
}
12116+
12117+
12118+
1205312119

1205412120
/* NORML
1205512121
* Variables: @src, @dest

0 commit comments

Comments
 (0)