implement decoding 8/16/32/64-bit store instructions -- all of Power ISA v3.1c Book I 3.3.3
All checks were successful
/ test (pull_request) Successful in 27m59s
All checks were successful
/ test (pull_request) Successful in 27m59s
This commit is contained in:
parent
706d54ae0d
commit
0824b63d31
4 changed files with 122563 additions and 87706 deletions
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
instruction::{
|
||||
AddSubMOp, BranchMOp, CompareMOp, CompareMode, ConditionMode, LoadMOp, LoadStoreConversion,
|
||||
LoadStoreWidth, LogicalFlagsMOp, LogicalFlagsMOpImm, LogicalMOp, Lut4, MOp, MOpDestReg,
|
||||
MOpRegNum, MoveRegMOp, OutputIntegerMode,
|
||||
MOpRegNum, MoveRegMOp, OutputIntegerMode, StoreMOp,
|
||||
},
|
||||
powerisa_instructions_xml::{
|
||||
InstructionBitFieldName, InstructionBitFieldsInner, Instructions, TextLineItem,
|
||||
|
|
@ -135,7 +135,7 @@ struct DecodeState {
|
|||
conditions: Option<&'static str>,
|
||||
header: &'static crate::powerisa_instructions_xml::InstructionHeader,
|
||||
insn: &'static crate::powerisa_instructions_xml::Instruction,
|
||||
output: Expr<ArrayVec<MOp, ConstUsize<2>>>,
|
||||
output: Expr<ArrayVec<MOp, ConstUsize<3>>>,
|
||||
is_illegal: Expr<Bool>,
|
||||
first_input: Expr<UInt<32>>,
|
||||
second_input: Expr<HdlOption<UInt<32>>>,
|
||||
|
|
@ -959,6 +959,196 @@ impl DecodeState {
|
|||
}
|
||||
}
|
||||
#[hdl]
|
||||
fn decode_store_8_16_32_64_bit(&mut self) {
|
||||
let (is_prefixed, is_update, is_indexed, width) = match self.mnemonic {
|
||||
"stb" => (false, false, false, 8),
|
||||
"pstb" => (true, false, false, 8),
|
||||
"stbx" => (false, false, true, 8),
|
||||
"stbu" => (false, true, false, 8),
|
||||
"stbux" => (false, true, true, 8),
|
||||
"sth" => (false, false, false, 16),
|
||||
"psth" => (true, false, false, 16),
|
||||
"sthx" => (false, false, true, 16),
|
||||
"sthu" => (false, true, false, 16),
|
||||
"sthux" => (false, true, true, 16),
|
||||
"stw" => (false, false, false, 32),
|
||||
"pstw" => (true, false, false, 32),
|
||||
"stwx" => (false, false, true, 32),
|
||||
"stwu" => (false, true, false, 32),
|
||||
"stwux" => (false, true, true, 32),
|
||||
"std" => (false, false, false, 64),
|
||||
"pstd" => (true, false, false, 64),
|
||||
"stdx" => (false, false, true, 64),
|
||||
"stdu" => (false, true, false, 64),
|
||||
"stdux" => (false, true, true, 64),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let width = match width {
|
||||
8 => LoadStoreWidth.Width8Bit(),
|
||||
16 => LoadStoreWidth.Width16Bit(),
|
||||
32 => LoadStoreWidth.Width32Bit(),
|
||||
64 => LoadStoreWidth.Width64Bit(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
#[hdl]
|
||||
fn do_store(
|
||||
this: &mut DecodeState,
|
||||
rs: Expr<FieldGpr>,
|
||||
ra: Expr<FieldGpr>,
|
||||
is_update: bool,
|
||||
width: Expr<LoadStoreWidth>,
|
||||
write_compute_ea_insn: impl FnOnce(Expr<MOp>, Expr<MOpRegNum>),
|
||||
) {
|
||||
connect(
|
||||
ArrayVec::len(this.output),
|
||||
2usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
let (ea_reg, ea_reg_conflict) = if is_update {
|
||||
let ea_reg = wire_with_loc(
|
||||
&format!("{}_ea_reg", this.mnemonic),
|
||||
SourceLocation::caller(),
|
||||
MOpRegNum,
|
||||
);
|
||||
connect(ea_reg, gpr(ra));
|
||||
let ea_reg_conflict = ra.reg_num.cmp_eq(rs.reg_num);
|
||||
#[hdl]
|
||||
if ea_reg_conflict {
|
||||
connect(ea_reg, MOpRegNum::power_isa_temp_reg());
|
||||
}
|
||||
(ea_reg, ea_reg_conflict)
|
||||
} else {
|
||||
(MOpRegNum::power_isa_temp_reg(), false.to_expr())
|
||||
};
|
||||
write_compute_ea_insn(this.output[0], ea_reg);
|
||||
connect(
|
||||
this.output[1],
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new([], []),
|
||||
[ea_reg.value, gpr(rs).value],
|
||||
width,
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
);
|
||||
#[hdl]
|
||||
if ea_reg_conflict {
|
||||
connect(
|
||||
ArrayVec::len(this.output),
|
||||
3usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
connect(
|
||||
this.output[2],
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new([gpr(ra)], []),
|
||||
[ea_reg.value],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
if is_prefixed {
|
||||
assert_eq!(self.arguments, Some("RS,D(RA),R"));
|
||||
assert!(!is_indexed);
|
||||
self.decode_scope(
|
||||
|this, (FieldRS(rs), FieldD0(d0), FieldD1(d1), FieldRA(ra), FieldR(r))| {
|
||||
let d = ((d0 << 16) + d1.cast_to(SInt[32])).cast_to_static::<SInt<_>>();
|
||||
do_store(this, rs, ra, is_update, width, |insn, ea_reg| {
|
||||
#[hdl]
|
||||
if r {
|
||||
connect(
|
||||
insn,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new([ea_reg], []),
|
||||
[MOpRegNum::const_zero().value; 2],
|
||||
d,
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
connect(
|
||||
insn,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new([ea_reg], []),
|
||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
||||
d,
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
} else if is_indexed {
|
||||
assert_eq!(self.arguments, Some("RS,RA,RB"));
|
||||
self.decode_scope(|this, (FieldRS(rs), FieldRA(ra), FieldRB(rb))| {
|
||||
do_store(this, rs, ra, is_update, width, |insn, ea_reg| {
|
||||
connect(
|
||||
insn,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new([ea_reg], []),
|
||||
[gpr_or_zero(ra).value, gpr(rb).value],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
} else if self.arguments == Some("RS,disp(RA)") {
|
||||
self.decode_scope(|this, (FieldRS(rs), FieldRA(ra), FieldDS(ds))| {
|
||||
do_store(this, rs, ra, is_update, width, |insn, ea_reg| {
|
||||
connect(
|
||||
insn,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new([ea_reg], []),
|
||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
||||
(ds << 2).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
assert_eq!(
|
||||
self.arguments,
|
||||
Some("RS,D(RA)"),
|
||||
"mnemonic={:?}",
|
||||
self.mnemonic,
|
||||
);
|
||||
self.decode_scope(|this, (FieldRS(rs), FieldRA(ra), FieldD(d))| {
|
||||
do_store(this, rs, ra, is_update, width, |insn, ea_reg| {
|
||||
connect(
|
||||
insn,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new([ea_reg], []),
|
||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
||||
d.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
#[hdl]
|
||||
fn decode_addi_paddi(&mut self) {
|
||||
match self.mnemonic {
|
||||
"addi" => {
|
||||
|
|
@ -1745,9 +1935,7 @@ const DECODE_FNS: &[(&[&str], DecodeFn)] = &[
|
|||
"stb", "pstb", "stbx", "stbu", "stbux", "sth", "psth", "sthx", "sthu", "sthux", "stw",
|
||||
"pstw", "stwx", "stwu", "stwux", "std", "pstd", "stdx", "stdu", "stdux",
|
||||
],
|
||||
|_state| {
|
||||
// TODO
|
||||
},
|
||||
DecodeState::decode_store_8_16_32_64_bit,
|
||||
),
|
||||
(&["lq", "plq", "stq", "pstq"], |_state| {
|
||||
// TODO
|
||||
|
|
@ -2008,7 +2196,7 @@ const DECODE_FNS: &[(&[&str], DecodeFn)] = &[
|
|||
#[hdl_module]
|
||||
pub fn decode_one_insn() {
|
||||
#[hdl]
|
||||
let output: ArrayVec<MOp, ConstUsize<2>> = m.output();
|
||||
let output: ArrayVec<MOp, ConstUsize<3>> = m.output();
|
||||
#[hdl]
|
||||
let is_illegal: Bool = m.output();
|
||||
#[hdl]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -11,6 +11,7 @@ mod fixed_point_arithmetic;
|
|||
mod fixed_point_compare;
|
||||
mod fixed_point_load;
|
||||
mod fixed_point_logical;
|
||||
mod fixed_point_store;
|
||||
mod move_to_from_system_register;
|
||||
mod prefixed_no_operation;
|
||||
|
||||
|
|
@ -18,7 +19,7 @@ pub struct TestCase {
|
|||
pub mnemonic: &'static str,
|
||||
pub first_input: u32,
|
||||
pub second_input: Option<u32>,
|
||||
pub output: SimValue<ArrayVec<MOp, ConstUsize<2>>>,
|
||||
pub output: SimValue<ArrayVec<MOp, ConstUsize<3>>>,
|
||||
pub loc: &'static std::panic::Location<'static>,
|
||||
}
|
||||
|
||||
|
|
@ -107,11 +108,38 @@ fn insn_double(
|
|||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn insn_triple(
|
||||
mnemonic: &'static str,
|
||||
first_input: u32,
|
||||
second_input: Option<u32>,
|
||||
insns: [impl ToSimValue<Type = MOp>; 3],
|
||||
) -> TestCase {
|
||||
let zero_mop = UInt::new_dyn(MOp.canonical().bit_width())
|
||||
.zero()
|
||||
.cast_bits_to(MOp);
|
||||
let mut single_storage = ArrayVec::new_sim(ArrayVec[MOp][ConstUsize], &zero_mop);
|
||||
ArrayVec::try_push_sim(&mut single_storage, &zero_mop).expect("known to have space");
|
||||
ArrayVec::try_push_sim(&mut single_storage, &zero_mop).expect("known to have space");
|
||||
ArrayVec::try_push_sim(&mut single_storage, zero_mop).expect("known to have space");
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[0] = insns[0].to_sim_value();
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[1] = insns[1].to_sim_value();
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[2] = insns[2].to_sim_value();
|
||||
TestCase {
|
||||
mnemonic,
|
||||
first_input,
|
||||
second_input,
|
||||
output: single_storage,
|
||||
loc: std::panic::Location::caller(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_cases() -> Vec<TestCase> {
|
||||
let mut retval = Vec::new();
|
||||
branch::test_cases_book_i_2_4_branch(&mut retval);
|
||||
condition_register::test_cases_book_i_2_5_condition_register(&mut retval);
|
||||
fixed_point_load::test_cases_book_i_3_3_2_fixed_point_load(&mut retval);
|
||||
fixed_point_store::test_cases_book_i_3_3_3_fixed_point_store(&mut retval);
|
||||
fixed_point_arithmetic::test_cases_book_i_3_3_9_fixed_point_arithmetic(&mut retval);
|
||||
fixed_point_compare::test_cases_book_i_3_3_10_fixed_point_compare(&mut retval);
|
||||
fixed_point_logical::test_cases_book_i_3_3_13_fixed_point_logical(&mut retval);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,512 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::test_cases::{TestCase, insn_double, insn_triple};
|
||||
use cpu::instruction::{
|
||||
AddSubMOp, LoadStoreConversion, LoadStoreWidth, MOpDestReg, MOpRegNum, MoveRegMOp,
|
||||
OutputIntegerMode, StoreMOp,
|
||||
};
|
||||
use fayalite::prelude::*;
|
||||
|
||||
/// covers instructions in PowerISA v3.1C Book I 3.3.3 Fixed-Point Store Instructions
|
||||
pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||
macro_rules! store_prefixed {
|
||||
(
|
||||
$mnemonic:literal $rs:literal, $disp:literal($ra:literal), $r:literal;
|
||||
$prefix:literal, $suffix:literal;
|
||||
$width:ident;
|
||||
) => {
|
||||
retval.push(insn_double(
|
||||
concat!($mnemonic, " ", $rs, ", ", $disp, "(", $ra, "), ", $r),
|
||||
$prefix,
|
||||
Some($suffix),
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $r != 0 || $ra == 0 {
|
||||
MOpRegNum::const_zero().value
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
||||
},
|
||||
MOpRegNum::const_zero().value,
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
$r != 0,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg().value,
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
macro_rules! store {
|
||||
(
|
||||
$mnemonic:literal $rs:literal, $disp:literal($ra:literal);
|
||||
$encoding:literal;
|
||||
$width:ident;
|
||||
) => {
|
||||
retval.push(insn_double(
|
||||
concat!($mnemonic, " ", $rs, ", ", $disp, "(", $ra, ")"),
|
||||
$encoding,
|
||||
None,
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero().value
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
||||
},
|
||||
MOpRegNum::const_zero().value,
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg().value,
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
macro_rules! store_update {
|
||||
(
|
||||
$mnemonic:literal $rs:literal, $disp:literal($ra:literal);
|
||||
$encoding:literal;
|
||||
$width:ident;
|
||||
) => {
|
||||
if $ra == $rs {
|
||||
retval.push(insn_triple(
|
||||
concat!($mnemonic, " ", $rs, ", ", $disp, "(", $ra, ")"),
|
||||
$encoding,
|
||||
None,
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
||||
MOpRegNum::const_zero().value,
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg().value,
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg().value],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
],
|
||||
));
|
||||
} else {
|
||||
retval.push(insn_double(
|
||||
concat!($mnemonic, " ", $rs, ", ", $disp, "(", $ra, ")"),
|
||||
$encoding,
|
||||
None,
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
||||
MOpRegNum::const_zero().value,
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! store_indexed {
|
||||
(
|
||||
$mnemonic:literal $rs:literal, $ra:literal, $rb:literal;
|
||||
$encoding:literal;
|
||||
$width:ident;
|
||||
) => {
|
||||
retval.push(insn_double(
|
||||
concat!($mnemonic, " ", $rs, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero().value
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
||||
},
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg().value,
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
macro_rules! store_update_indexed {
|
||||
(
|
||||
$mnemonic:literal $rs:literal, $ra:literal, $rb:literal;
|
||||
$encoding:literal;
|
||||
$width:ident;
|
||||
) => {
|
||||
if $ra == $rs {
|
||||
retval.push(insn_triple(
|
||||
concat!($mnemonic, " ", $rs, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg().value,
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg().value],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
],
|
||||
));
|
||||
} else {
|
||||
retval.push(insn_double(
|
||||
concat!($mnemonic, " ", $rs, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero().value
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
||||
},
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
store! {
|
||||
"stb" 3, 0x1234(4);
|
||||
0x98641234;
|
||||
Width8Bit;
|
||||
}
|
||||
store! {
|
||||
"stb" 3, 0x1234(0);
|
||||
0x98601234;
|
||||
Width8Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstb" 3, 0x123456789(4), 0;
|
||||
0x06012345, 0x98646789;
|
||||
Width8Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstb" 3, 0x123456789(0), 0;
|
||||
0x06012345, 0x98606789;
|
||||
Width8Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstb" 3, 0x123456789(0), 1;
|
||||
0x06112345, 0x98606789;
|
||||
Width8Bit;
|
||||
}
|
||||
store_indexed! {
|
||||
"stbx" 3, 4, 5;
|
||||
0x7c6429ae;
|
||||
Width8Bit;
|
||||
}
|
||||
store_indexed! {
|
||||
"stbx" 3, 0, 5;
|
||||
0x7c6029ae;
|
||||
Width8Bit;
|
||||
}
|
||||
store_update! {
|
||||
"stbu" 3, 0x1234(4);
|
||||
0x9c641234;
|
||||
Width8Bit;
|
||||
}
|
||||
store_update! {
|
||||
"stbu" 3, 0x1234(3);
|
||||
0x9c631234;
|
||||
Width8Bit;
|
||||
}
|
||||
store_update_indexed! {
|
||||
"stbux" 3, 4, 5;
|
||||
0x7c6429ee;
|
||||
Width8Bit;
|
||||
}
|
||||
store_update_indexed! {
|
||||
"stbux" 3, 3, 5;
|
||||
0x7c6329ee;
|
||||
Width8Bit;
|
||||
}
|
||||
|
||||
store! {
|
||||
"sth" 3, 0x1234(4);
|
||||
0xb0641234;
|
||||
Width16Bit;
|
||||
}
|
||||
store! {
|
||||
"sth" 3, 0x1234(0);
|
||||
0xb0601234;
|
||||
Width16Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"psth" 3, 0x123456789(4), 0;
|
||||
0x06012345, 0xb0646789;
|
||||
Width16Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"psth" 3, 0x123456789(0), 0;
|
||||
0x06012345, 0xb0606789;
|
||||
Width16Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"psth" 3, 0x123456789(0), 1;
|
||||
0x06112345, 0xb0606789;
|
||||
Width16Bit;
|
||||
}
|
||||
store_indexed! {
|
||||
"sthx" 3, 4, 5;
|
||||
0x7c642b2e;
|
||||
Width16Bit;
|
||||
}
|
||||
store_indexed! {
|
||||
"sthx" 3, 0, 5;
|
||||
0x7c602b2e;
|
||||
Width16Bit;
|
||||
}
|
||||
store_update! {
|
||||
"sthu" 3, 0x1234(4);
|
||||
0xb4641234;
|
||||
Width16Bit;
|
||||
}
|
||||
store_update! {
|
||||
"sthu" 3, 0x1234(3);
|
||||
0xb4631234;
|
||||
Width16Bit;
|
||||
}
|
||||
store_update_indexed! {
|
||||
"sthux" 3, 4, 5;
|
||||
0x7c642b6e;
|
||||
Width16Bit;
|
||||
}
|
||||
store_update_indexed! {
|
||||
"sthux" 3, 3, 5;
|
||||
0x7c632b6e;
|
||||
Width16Bit;
|
||||
}
|
||||
|
||||
store! {
|
||||
"stw" 3, 0x1234(4);
|
||||
0x90641234;
|
||||
Width32Bit;
|
||||
}
|
||||
store! {
|
||||
"stw" 3, 0x1234(0);
|
||||
0x90601234;
|
||||
Width32Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstw" 3, 0x123456789(4), 0;
|
||||
0x06012345, 0x90646789;
|
||||
Width32Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstw" 3, 0x123456789(0), 0;
|
||||
0x06012345, 0x90606789;
|
||||
Width32Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstw" 3, 0x123456789(0), 1;
|
||||
0x06112345, 0x90606789;
|
||||
Width32Bit;
|
||||
}
|
||||
store_indexed! {
|
||||
"stwx" 3, 4, 5;
|
||||
0x7c64292e;
|
||||
Width32Bit;
|
||||
}
|
||||
store_indexed! {
|
||||
"stwx" 3, 0, 5;
|
||||
0x7c60292e;
|
||||
Width32Bit;
|
||||
}
|
||||
store_update! {
|
||||
"stwu" 3, 0x1234(4);
|
||||
0x94641234;
|
||||
Width32Bit;
|
||||
}
|
||||
store_update! {
|
||||
"stwu" 3, 0x1234(3);
|
||||
0x94631234;
|
||||
Width32Bit;
|
||||
}
|
||||
store_update_indexed! {
|
||||
"stwux" 3, 4, 5;
|
||||
0x7c64296e;
|
||||
Width32Bit;
|
||||
}
|
||||
store_update_indexed! {
|
||||
"stwux" 3, 3, 5;
|
||||
0x7c63296e;
|
||||
Width32Bit;
|
||||
}
|
||||
|
||||
store! {
|
||||
"std" 3, 0x1234(4);
|
||||
0xf8641234;
|
||||
Width64Bit;
|
||||
}
|
||||
store! {
|
||||
"std" 3, 0x1234(0);
|
||||
0xf8601234;
|
||||
Width64Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstd" 3, 0x123456789(4), 0;
|
||||
0x04012345, 0xf4646789;
|
||||
Width64Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstd" 3, 0x123456789(0), 0;
|
||||
0x04012345, 0xf4606789;
|
||||
Width64Bit;
|
||||
}
|
||||
store_prefixed! {
|
||||
"pstd" 3, 0x123456789(0), 1;
|
||||
0x04112345, 0xf4606789;
|
||||
Width64Bit;
|
||||
}
|
||||
store_indexed! {
|
||||
"stdx" 3, 4, 5;
|
||||
0x7c64292a;
|
||||
Width64Bit;
|
||||
}
|
||||
store_indexed! {
|
||||
"stdx" 3, 0, 5;
|
||||
0x7c60292a;
|
||||
Width64Bit;
|
||||
}
|
||||
store_update! {
|
||||
"stdu" 3, 0x1234(4);
|
||||
0xf8641235;
|
||||
Width64Bit;
|
||||
}
|
||||
store_update! {
|
||||
"stdu" 3, 0x1234(3);
|
||||
0xf8631235;
|
||||
Width64Bit;
|
||||
}
|
||||
store_update_indexed! {
|
||||
"stdux" 3, 4, 5;
|
||||
0x7c64296a;
|
||||
Width64Bit;
|
||||
}
|
||||
store_update_indexed! {
|
||||
"stdux" 3, 3, 5;
|
||||
0x7c63296a;
|
||||
Width64Bit;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue