@@ -446,15 +446,15 @@ pub const Instruction = union(enum) {
446446 pre_post : u1 ,
447447 up_down : u1 ,
448448 psr_or_user : u1 ,
449- write_back : u1 ,
449+ write_back : bool ,
450450 load_store : u1 ,
451451 ) Instruction {
452452 return Instruction {
453453 .BlockDataTransfer = .{
454454 .register_list = @bitCast (u16 , reg_list ),
455455 .rn = rn .id (),
456456 .load_store = load_store ,
457- .write_back = write_back ,
457+ .write_back = if ( write_back ) 1 else 0 ,
458458 .psr_or_user = psr_or_user ,
459459 .up_down = up_down ,
460460 .pre_post = pre_post ,
@@ -644,14 +644,50 @@ pub const Instruction = union(enum) {
644644
645645 // Block data transfer
646646
647- pub fn ldm (cond : Condition , rn : Register , reg_list : RegisterList ) Instruction {
648- return blockDataTransfer (cond , rn , reg_list , 1 , 0 , 0 , 0 , 1 );
647+ pub fn ldmda (cond : Condition , rn : Register , write_back : bool , reg_list : RegisterList ) Instruction {
648+ return blockDataTransfer (cond , rn , reg_list , 0 , 0 , 0 , write_back , 1 );
649649 }
650650
651- pub fn stm (cond : Condition , rn : Register , reg_list : RegisterList ) Instruction {
652- return blockDataTransfer (cond , rn , reg_list , 1 , 0 , 0 , 0 , 0 );
651+ pub fn ldmdb (cond : Condition , rn : Register , write_back : bool , reg_list : RegisterList ) Instruction {
652+ return blockDataTransfer (cond , rn , reg_list , 1 , 0 , 0 , write_back , 1 );
653+ }
654+
655+ pub fn ldmib (cond : Condition , rn : Register , write_back : bool , reg_list : RegisterList ) Instruction {
656+ return blockDataTransfer (cond , rn , reg_list , 1 , 1 , 0 , write_back , 1 );
657+ }
658+
659+ pub fn ldmia (cond : Condition , rn : Register , write_back : bool , reg_list : RegisterList ) Instruction {
660+ return blockDataTransfer (cond , rn , reg_list , 0 , 1 , 0 , write_back , 1 );
661+ }
662+
663+ pub const ldmfa = ldmda ;
664+ pub const ldmea = ldmdb ;
665+ pub const ldmed = ldmib ;
666+ pub const ldmfd = ldmia ;
667+ pub const ldm = ldmia ;
668+
669+ pub fn stmda (cond : Condition , rn : Register , write_back : bool , reg_list : RegisterList ) Instruction {
670+ return blockDataTransfer (cond , rn , reg_list , 0 , 0 , 0 , write_back , 0 );
653671 }
654672
673+ pub fn stmdb (cond : Condition , rn : Register , write_back : bool , reg_list : RegisterList ) Instruction {
674+ return blockDataTransfer (cond , rn , reg_list , 1 , 0 , 0 , write_back , 0 );
675+ }
676+
677+ pub fn stmib (cond : Condition , rn : Register , write_back : bool , reg_list : RegisterList ) Instruction {
678+ return blockDataTransfer (cond , rn , reg_list , 1 , 1 , 0 , write_back , 0 );
679+ }
680+
681+ pub fn stmia (cond : Condition , rn : Register , write_back : bool , reg_list : RegisterList ) Instruction {
682+ return blockDataTransfer (cond , rn , reg_list , 0 , 1 , 0 , write_back , 0 );
683+ }
684+
685+ pub const stmed = stmda ;
686+ pub const stmfd = stmdb ;
687+ pub const stmfa = stmib ;
688+ pub const stmea = stmia ;
689+ pub const stm = stmia ;
690+
655691 // Branch
656692
657693 pub fn b (cond : Condition , offset : i24 ) Instruction {
@@ -738,10 +774,14 @@ test "serialize instructions" {
738774 .inst = Instruction .bkpt (42 ),
739775 .expected = 0b1110_0001_0010_000000000010_0111_1010 ,
740776 },
741- .{ // stmfd r9, {r0}
742- .inst = Instruction .stm (.al , .r9 , .{ .r0 = true }),
777+ .{ // stmdb r9, {r0}
778+ .inst = Instruction .stmdb (.al , .r9 , false , .{ .r0 = true }),
743779 .expected = 0b1110_100_1_0_0_0_0_1001_0000000000000001 ,
744780 },
781+ .{ // ldmea r4!, {r2, r5}
782+ .inst = Instruction .ldmea (.al , .r4 , true , .{ .r2 = true , .r5 = true }),
783+ .expected = 0b1110_100_1_0_0_1_1_0100_0000000000100100 ,
784+ },
745785 };
746786
747787 for (testcases ) | case | {
0 commit comments