Exemplo n.º 1
0
?>

<p>

ARM multiply instructions are basically plain multiplies or multiply
with accumulate. They are emulated with three different instructions:
INIT, IMLA, IMLB. For simplicity a multiply instruction always takes
16 cycles; early termination is not supported.

INIT[CC]A Rm, Rn/0
IMLACPA Acc, Rs
IMLBCPA Acc, #0 14 times
IMLBCPA[S] Acc, #0 -> Rd

</p>

<?php 
arm_emulation_table_start();
arm_emulation_table_instruction("MUL[CC] Rd, Rm, Rs", "\n    INIT[CC]A Rm, #0<br>\n    IMLACPA Acc, Rs<br>\n    IMLBCPA Acc, #0 <i>(14 times)</i><br>\n    IMLBCPA[F] Acc, #0 -> Rd", "No restrictions", "");
arm_emulation_table_instruction("MLA[CC] Rd, Rm, Rs, Rn", "\n    INIT[CC]A Rm, Rn<br>\n    IMLACPA Acc, Rs<br>\n    IMLBCPA Acc, #0 <i>(14 times)</i><br>\n    IMLBCPA[F] Acc, #0 -> Rd", "No restrictions", "");
arm_emulation_table_instruction("MUL[CC]S Rd, Rm, Rs", "\n    INIT[CC]A Rm, #0<br>\n    IMLACPA Acc, Rs<br>\n    IMLBCPA Acc, #0 <i>(14 times)</i><br>\n    IMLBCPAS[F] Acc, #0 -> Rd", "No restrictions", "<em>Differs from ARM - V is corrupted</em>");
arm_emulation_table_instruction("MLA[CC]S Rd, Rm, Rs, Rn", "\n    INIT[CC]A Rm, Rn<br>\n    IMLACPA Acc, Rs<br>\n    IMLBCPA Acc, #0 <i>(14 times)</i><br>\n    IMLBCPAS[F] Acc, #0 -> Rd", "No restrictions", "<em>Differs from ARM - V is corrupted</em>");
arm_emulation_table_end();
?>

<?php 
page_ep();
include "{$toplevel}web_assist/web_footer.php";
?>

Exemplo n.º 2
0
occur, whether they are forwards or backwards.

</p>

<p>

Conditional branches with link are emulated by inserting two internal
instructions in to the pipeline; one with the reverse condition of the
instruction with flush to force a branch to PC+8-4 if the condition is
not met, and the other with the current condition to set the link
register on a correctly predicted branch. The program counter is also
updated with the branch target address.

</p>

<?php 
page_section("emulation_details", "Emulation details");
arm_emulation_table_start();
arm_emulation_table_instruction("B {offset}", "", "Guaranteed branch", "Changes PC to PC+8+offset");
arm_emulation_table_instruction("B[CC] {offset}", "", "CC will be met<br>Guaranteed branch", "Changes PC to PC+8+offset");
arm_emulation_table_instruction("B[CC] {negative offset}", "SUB{!CC}F PC, #4 -> PC", "CC may not be met<br>Predicted branch", "Changes PC to PC+8+offset<br>If mispredicted then instruction will execute and reset PC to the correct path");
arm_emulation_table_instruction("B[CC] {positive offset}", "MOV{CC}F #target -> PC", "CC may not be met<br>Unpredicted branch", "If mispredicted then instruction will execute and set PC to branch target");
arm_emulation_table_instruction("BL {offset}", "SUB PC, #4 -> R14", "Guaranteed branch with link", "Changes PC to PC+8+offset");
arm_emulation_table_instruction("BL[CC] {offset}", "SUB PC, #4 -> R14", "CC will be met<br>Guaranteed branch with link", "Changes PC to PC+8+offset");
arm_emulation_table_instruction("BL[CC] {offset}", "SUB{!CC}F PC, #4 -> PC<br>SUB PC, #4 -> R14", "CC may not be met<br>Conditional branch with link", "Changes PC to PC+8+offset<br>If mispredicted then instruction will execute and reset PC to the correct path, and R14 will not be written");
arm_emulation_table_end();
page_ep();
include "{$toplevel}web_assist/web_footer.php";
?>

Exemplo n.º 3
0
<li>
If the shift is by register Rs, then check if it should be replaced with ACC or PC: if it is R15 then replace it with 'PC', and the instruction address plus 8 will be passed in to the internal pipeline as the PC value; if instead it matches the tracking accumulator indicator then replace it with 'ACC'. If Rs is not replaced, then use it as is. This will be the second operand of the first internal instruction.

<li>
If the shift is immediate then use that as the second operand of the first internal instruction.

</ol>

<?php 
arm_emulation_table_start();
arm_emulation_table_instruction("MOV    Rd, Rm, LSL #imm", "ILSL Rm, #imm<br>IMOVA   SHF -> Rd", $rd_not_pc, "{$repl_shf}<br>{$move_ops}<br>{$effects_acc}");
arm_emulation_table_instruction("ADD    Rd, Rn, Rm, LSL Rs", "ILSL Rm, Rs<br>IADDA   Rn, SHF -> Rd", $rd_not_pc, "{$repl_shf}<br>{$repl_rn_rs}<br>{$arith_logic_ops}<br>{$effects_acc}");
arm_emulation_table_instruction("MOV    PC, Rm, LSL Rs", "ILSL Rm, Rs<br>IMOVAF  SHF -> PC", "", "{$repl_shf}<br>{$repl_rs}<br>{$move_ops}<br>{$effects_acc}");
arm_emulation_table_instruction("ADD    PC, Rn, Rm, LSL #imm", "ILSL Rm, #imm<br>IADDAF  Rn, SHF -> PC", "", "{$repl_shf}<br>{$repl_rn}<br>{$arith_logic_ops}<br>{$effects_nothing}");
arm_emulation_table_instruction("MOVS   Rd, Rm, LSL #imm", "ILSL Rm, #imm<br>IMOVSPA   SHF -> Rd", $rd_not_pc, "{$repl_shf}<br>{$move_ops}<br>{$effects_acc_zn}");
arm_emulation_table_instruction("CMP[S] Rn, Rm, LSL #imm", "ILSL Rm, #imm<br>ISUBSP   Rn, SHF", "", "{$repl_shf}<br>{$repl_rn}<br>{$compare_ops}<br>{$effects_zcvn}");
arm_emulation_table_instruction("TST[S] Rn, Rm, LSL #imm", "ILSL Rm, #imm<br>IANDSP   Rn, SHF", "", "{$repl_shf}<br>{$repl_rn}<br>{$compare_ops}<br>{$effects_zn}");
arm_emulation_table_instruction("ADDEQS   Rd, Rn, Rm, LSL #imm", "ILSL Rm, #imm<br>IADDEQSP  Rn, SHF -> Rd", $rd_not_pc, "{$repl_shf}<br>{$repl_rn}<br>{$arith_ops}<br>{$effects_acc_zcvn}<br>{$conds}");
arm_emulation_table_instruction("BICS   Rd, Rn, Rm, LSL #imm", "ILSL Rm, #imm<br>IBICSPA  Rn, SHF -> Rd", $rd_not_pc, "{$repl_shf}<br>{$repl_rn}<br>{$logic_ops}<br>{$effects_acc_zn}");
arm_emulation_table_end();
?>

</p>

<?php 
page_ep();
include "{$toplevel}web_assist/web_footer.php";
?>

arm_emulation_table_instruction("LDR[CC] Rd, [Rn], +/-Rm", "ILDR[CC]A[S] #0 (Rn), +/-Rm -> Rd<br>MOVCP ACC -> Rn", $rd_rn_not_pc, "{$repl_rn_rm}<br>");
arm_emulation_table_instruction("LDR[CC] PC, [Rn], +/-Rm", "ILDR[CC]A[S] #0 (Rn), +/-Rm -> PC<br>MOVCPF ACC -> Rn", $rn_not_pc, "{$repl_rn_rm}<br>");
arm_emulation_table_instruction("LDR[CC] Rd, [Rn], +/-Rm, SHF #imm", "ILSL Rm, #imm<br>ILDR[CC]A[S] #0 (Rn), +/-SHF -> Rd<br>MOVCP ACC -> Rn", $rd_rn_not_pc, "{$repl_rn_rm}<br>");
arm_emulation_table_instruction("LDR[CC] PC, [Rn], +/-Rm, SHF #imm", "ILSL Rm, #imm<br>ILDR[CC]A[S] #0 (Rn), +/-SHF -> PC<br>MOVCPF ACC -> Rn", $rn_not_pc, "{$repl_rn_rm}<br>");
arm_emulation_table_end();
?>

<?php 
page_section("stores", "Stores");
arm_emulation_table_start();
arm_emulation_table_instruction("STR[CC] Rd, [Rn, #0]", "ISTR[CC][S] #0 (Rn) <- Rd", "", $repl_rn);
arm_emulation_table_instruction("STR[CC] Rd, [Rn, #0]!", "ISTR[CC][S] #0 (Rn) <- Rd", "", $repl_rn);
arm_emulation_table_instruction("STR[CC] Rd, [Rn], #0", "ISTR[CC][S] #0 (Rn) <- Rd", "", $repl_rn);
arm_emulation_table_instruction("STR[CC] Rd, [Rn, #+/-imm]", "IADD[CC]AC/ISUB[CC]AC Rn, #imm<br>ISTRCP[S] #0 (ACC, +/-SHF) <- Rd", "", $repl_rn);
arm_emulation_table_instruction("STR[CC] Rd, [Rn, +/-Rm]", "IADD[CC]AC/ISUB[CC]AC Rn, Rm<br>ISTRCP[S] #0 (ACC, +/-SHF) <- Rd", "", $repl_rn_rm);
arm_emulation_table_instruction("STR[CC] Rd, [Rn, +/-Rm, SHF #imm]", "ISHF[CC] Rm, #imm<br>ISTRCPA[S] #0 (Rn, +/-SHF) <- Rd", "", $repl_rn_rm);
arm_emulation_table_instruction("STR[CC] Rd, [Rn, #+/-imm]!", "IADDAC/ISUBAC Rn, #imm<br>ISTR[CC]A[S] #0 (ACC, +SHF) <- Rd -> Rn", "", $repl_rn);
arm_emulation_table_instruction("STR[CC] Rd, [Rn, +/-Rm]!", "IADDAC/ISUBAC Rn, Rm<br>ISTR[CC]A[S] #0 (ACC, +SHF) <- Rd -> Rn", "", $repl_rn_rm);
arm_emulation_table_instruction("STR[CC] Rd, [Rn, +/-Rm, SHF #imm]!", "ILSL Rm, #imm<br>ISTR[CC]A[S] #0 (Rn, +/-SHF) <- Rd -> Rn", "", $repl_rn_rm);
arm_emulation_table_instruction("STR[CC] Rd, [Rn], #+/-imm", "ISTR[CC][S] #0 (Rn) <- Rd<br>IADDCPA/ISUBCPA Rn, #imm -> Rn", "", $repl_rn);
arm_emulation_table_instruction("STR[CC] Rd, [Rn], +/-Rm", "ISTR[CC][S] #0 (Rn) <- Rd<br>IADDCPA/ISUBCPA Rn, Rm -> Rn", "", $repl_rn_rm);
arm_emulation_table_instruction("STR[CC] Rd, [Rn], +/-Rm, SHF #imm", "ISHF[CC] Rm, #imm<br>ISTRCPA[S] #0 (Rn), +/-SHF <- Rd -> Rn", "", $repl_rn_rm);
arm_emulation_table_end();
?>

<?php 
page_ep();
include "{$toplevel}web_assist/web_footer.php";
?>

arm_emulation_table_instruction("LDM[CC]IA Rn, {Ri0, Ri1, ... Rik}", "ILDR[CC]A[S] #k (Rn), #+4 -> Ri0<br>ILDRCPA[S] #k-1 (Acc), #+4 -> Ri1<br>...<br>ILDRCPA[A][F] #0 (Acc), #+4 -> Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("LDM[CC]IA Rn!, {Ri0, Ri1, ... Rik}", "ILDR[CC]A[S] #k (Rn), #+4 -> Ri0<br>ILDRCPA[S] #k-1 (Acc), #+4 -> Ri1<br>...<br>ILDRCPA[S] #0 (Acc), #+4 -> Rik<br>IMOVCP[F] Acc -> Rn", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("LDM[CC]IB Rn, {Ri0, Ri1, ... Rik}", "ILDR[CC]A[S] #k (Rn, #+4) -> Ri0<br>ILDRCPA[S] #k-1 (Acc, #+4) -> Ri1<br>...<br>ILDRCPA[S][F] #0 (Acc, #+4) -> Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("LDM[CC]IB Rn!, {Ri0, Ri1, ... Rik}", "ILDR[CC]A[S] #k (Rn, #+4) -> Ri0<br>ILDRCPA[S] #k-1 (Acc, #+4) -> Ri1<br>...<br>ILDRCPA[S] #0 (Acc, #+4) -> Rik<br>IMOVCP[F] Acc -> Rn", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("LDM[CC]DB Rn, {Ri0, Ri1, ... Rik}", "ISUB[CC]A Rn, #k*4<br>ILDRCPA[S] #k (Acc), #+4 -> Ri0<br>ILDRCPA[S] #k-1 (Acc), #+4 -> Ri1<br>...<br>ILDRCPA[S][F] #0 (Acc), #+4 -> Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("LDM[CC]DB Rn!, {Ri0, Ri1, ... Rik}", "ISUB[CC]A Rn, #k*4 -> Rn<br>ILDRCPA[S] #k (Acc), #+4 -> Ri0<br>ILDRCPA[S] #k-1 (Acc), #+4 -> Ri1<br>...<br>ILDRCPA[S][F] #0 (Acc), #+4 -> Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("LDM[CC]DA Rn, {Ri0, Ri1, ... Rik}", "ISUB[CC]A Rn, #k*4<br>ILDRCPA[S] #k (Acc, #+4) -> Ri0<br>ILDRCPA[S] #k-1 (Acc, #+4) -> Ri1<br>...<br>ILDRCPA[S][F] #0 (Acc, #+4) -> Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("LDM[CC]DA Rn!, {Ri0, Ri1, ... Rik}", "ISUB[CC]A Rn, #k*4 -> Rn<br>ILDRCPA[S] #k (Acc, #+4) -> Ri0<br>ILDRCPA[S] #k-1 (Acc, #+4) -> Ri1<br>...<br>ILDRCPA[S][F] #0 (Acc, #+4) -> Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_end();
?>

<?php 
page_section("stores", "Stores");
arm_emulation_table_start();
arm_emulation_table_instruction("STM[CC]IA Rn, {Ri0, Ri1, ... Rik}", "ISTR[CC]A[S] #k (Rn), #+4 <- Ri0<br>ISTRCPA[S] #k-1 (Acc), #+4 <- Ri1<br>...<br>ISTRCPA[S] #0 (Acc), #+4 <- Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("STM[CC]IA Rn!, {Ri0, Ri1, ... Rik}", "ISTR[CC]A[S] #k (Rn), #+4 <- Ri0<br>ISTRCPA[S] #k-1 (Acc), #+4 <- Ri1<br>...<br>ISTRCPA[S] #0 (Acc), #+4 <- Rik -> Rn", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("STM[CC]IB Rn, {Ri0, Ri1, ... Rik}", "ISTR[CC]A[S] #k (Rn, #+4) <- Ri0<br>ISTRCPA[S] #k-1 (Acc, #+4) <- Ri1<br>...<br>ISTRCPA[S] #0 (Acc, #+4) <- Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("STM[CC]IB Rn!, {Ri0, Ri1, ... Rik}", "ISTR[CC]A[S] #k (Rn, #+4) <- Ri0<br>ISTRCPA[S] #k-1 (Acc, #+4) <- Ri1<br>...<br>ISTRCPA[S] #0 (Acc, #+4) <- Rik -> Rn", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("STM[CC]DB Rn, {Ri0, Ri1, ... Rik}", "ISUB[CC]A Rn, #k*4<br>ISTRCPA[S] #k (Acc), #+4 <- Ri0<br>ISTRCPA[S] #k-1 (Acc), #+4 <- Ri1<br>...<br>ISTRCPA[S] #0 (Acc), #+4 <- Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("STM[CC]DB Rn!, {Ri0, Ri1, ... Rik}", "ISUB[CC]A Rn, #k*4 -> Rn<br>ISTRCPA[S] #k (Acc), #+4 <- Ri0<br>ISTRCPA[S] #k-1 (Acc), #+4 <- Ri1<br>...<br>ISTRCPA[S] #0 (Acc), #+4 <- Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("STM[CC]DA Rn, {Ri0, Ri1, ... Rik}", "ISUB[CC]A Rn, #k*4<br>ISTRCPA[S] #k (Acc, #+4) <- Ri0<br>ISTRCPA[S] #k-1 (Acc, #+4) <- Ri1<br>...<br>ISTRCPA[S] #0 (Acc, #+4) <- Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_instruction("STM[CC]DA Rn!, {Ri0, Ri1, ... Rik}", "ISUB[CC]A Rn, #k*4 -> Rn<br>ISTRCPA[S] #k (Acc, #+4) <- Ri0<br>ISTRCPA[S] #k-1 (Acc, #+4) <- Ri1<br>...<br>ISTRCPA[S] #0 (Acc, #+4) <- Rik", $rn_not_pc, $repl_rn);
arm_emulation_table_end();
?>

<?php 
page_ep();
include "{$toplevel}web_assist/web_footer.php";
?>