mirror of
https://github.com/encounter/ppc750cl.git
synced 2025-09-21 18:49:52 +00:00
support mnemonic suffixes
This commit is contained in:
parent
756e23f240
commit
40142dcd9b
@ -1,4 +1,4 @@
|
|||||||
use std::fmt::{Display, LowerHex, UpperHex, Formatter};
|
use std::fmt::{Display, Formatter, LowerHex, UpperHex};
|
||||||
|
|
||||||
use num_traits::PrimInt;
|
use num_traits::PrimInt;
|
||||||
|
|
||||||
@ -14,8 +14,7 @@ impl Display for FormattedIns {
|
|||||||
|
|
||||||
impl FormattedIns {
|
impl FormattedIns {
|
||||||
fn fmt_ins(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt_ins(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let mnemonic = self.0.op.mnemonic();
|
write!(f, "{}{} ", self.0.op.mnemonic(), self.0.modifiers())?;
|
||||||
write!(f, "{} ", mnemonic)?;
|
|
||||||
let fields = self.0.fields();
|
let fields = self.0.fields();
|
||||||
let mut writing_offset = false;
|
let mut writing_offset = false;
|
||||||
for (i, field) in fields.iter().enumerate() {
|
for (i, field) in fields.iter().enumerate() {
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
|
use std::fmt::Formatter;
|
||||||
|
use std::ops::Range;
|
||||||
|
|
||||||
|
use num_traits::AsPrimitive;
|
||||||
|
|
||||||
|
use ppc750cl_macros::{fields, ins_impl, opcodes};
|
||||||
|
|
||||||
|
pub use crate::iter::{disasm_iter, DisasmIterator};
|
||||||
|
|
||||||
pub mod formatter;
|
pub mod formatter;
|
||||||
mod iter;
|
mod iter;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
pub use crate::formatter::FormattedIns;
|
||||||
pub use crate::Field;
|
pub use crate::Field;
|
||||||
pub use crate::Field::*;
|
pub use crate::Field::*;
|
||||||
pub use crate::Ins;
|
pub use crate::Ins;
|
||||||
pub use crate::formatter::FormattedIns;
|
|
||||||
pub use crate::Opcode::*;
|
pub use crate::Opcode::*;
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
Bit, BranchDest, CRBit, CRField, Offset, OpaqueU, Simm, Uimm, FPR, GPR, GQR, SPR, SR,
|
Bit, BranchDest, CRBit, CRField, Offset, OpaqueU, Simm, Uimm, FPR, GPR, GQR, SPR, SR,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
use ppc750cl_macros::{fields, ins_impl, opcodes};
|
|
||||||
|
|
||||||
//pub use crate::formatter::AsmFormatter;
|
|
||||||
//use crate::formatter::SimpleFormatter;
|
|
||||||
pub use crate::iter::{disasm_iter, DisasmIterator};
|
|
||||||
|
|
||||||
macro_rules! field_arg {
|
macro_rules! field_arg {
|
||||||
($name:ident, $typ:ident) => {
|
($name:ident, $typ:ident) => {
|
||||||
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
@ -25,6 +28,21 @@ macro_rules! field_arg {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit(x: u32, idx: usize) -> bool {
|
||||||
|
((x >> (32 - idx - 1)) & 1) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn bits<F>(x: u32, range: Range<usize>) -> F
|
||||||
|
where
|
||||||
|
F: 'static + std::marker::Copy,
|
||||||
|
u32: AsPrimitive<F>,
|
||||||
|
{
|
||||||
|
let masked: u32 = (x >> (32 - range.end)) & ((1 << range.len()) - 1);
|
||||||
|
masked.as_()
|
||||||
|
}
|
||||||
|
|
||||||
// General-purpose register.
|
// General-purpose register.
|
||||||
field_arg!(GPR, u8);
|
field_arg!(GPR, u8);
|
||||||
// Floating-point register (direct or paired-singles mode).
|
// Floating-point register (direct or paired-singles mode).
|
||||||
@ -55,10 +73,48 @@ field_arg!(OpaqueU, u32);
|
|||||||
// Generate the Field enum and impls.
|
// Generate the Field enum and impls.
|
||||||
fields!();
|
fields!();
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Modifiers {
|
||||||
|
pub oe: bool,
|
||||||
|
pub rc: bool,
|
||||||
|
pub lk: bool,
|
||||||
|
pub aa: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Modifiers {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self.aa {
|
||||||
|
write!(f, "a")?;
|
||||||
|
}
|
||||||
|
if self.lk {
|
||||||
|
write!(f, "l")?;
|
||||||
|
}
|
||||||
|
if self.oe {
|
||||||
|
write!(f, "o")?;
|
||||||
|
}
|
||||||
|
if self.rc {
|
||||||
|
write!(f, ".")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the Opcode enum and impls.
|
// Generate the Opcode enum and impls.
|
||||||
// TODO This could be made more readable with a derive over an empty enum.
|
// TODO This could be made more readable with a derive over an empty enum.
|
||||||
opcodes!();
|
opcodes!();
|
||||||
|
|
||||||
|
impl Opcode {
|
||||||
|
/// Detects the opcode of a machine code instruction.
|
||||||
|
pub fn detect(code: u32) -> Self {
|
||||||
|
Self::_detect(code) // auto-generated
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints the basic mnemonic of an opcode.
|
||||||
|
pub fn mnemonic(self) -> &'static str {
|
||||||
|
self._mnemonic() // auto-generated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Opcode {
|
impl Default for Opcode {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Opcode::Illegal
|
Opcode::Illegal
|
||||||
@ -95,6 +151,11 @@ impl Ins {
|
|||||||
self._fields() // auto-generated
|
self._fields() // auto-generated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the modifiers of an instruction.
|
||||||
|
pub fn modifiers(&self) -> Modifiers {
|
||||||
|
self._modifiers() // auto-generated
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the defs of an instruction.
|
/// Gets the defs of an instruction.
|
||||||
pub fn defs(&self) -> Vec<Field> {
|
pub fn defs(&self) -> Vec<Field> {
|
||||||
self._defs() // auto-generated
|
self._defs() // auto-generated
|
||||||
@ -104,6 +165,16 @@ impl Ins {
|
|||||||
pub fn uses(&self) -> Vec<Field> {
|
pub fn uses(&self) -> Vec<Field> {
|
||||||
self._uses() // auto-generated
|
self._uses() // auto-generated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the given bit from the machine code instruction.
|
||||||
|
pub fn bit(&self, idx: usize) -> bool {
|
||||||
|
bit(self.code, idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the given range of btis from the machine code instruction.
|
||||||
|
pub fn bits(&self, range: Range<usize>) -> u32 {
|
||||||
|
bits(self.code, range)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ins_impl!();
|
ins_impl!();
|
||||||
|
@ -4,6 +4,10 @@ macro_rules! assert_asm {
|
|||||||
($ins:ident, $disasm:literal) => {{
|
($ins:ident, $disasm:literal) => {{
|
||||||
assert_eq!(format!("{}", FormattedIns($ins)), $disasm)
|
assert_eq!(format!("{}", FormattedIns($ins)), $disasm)
|
||||||
}};
|
}};
|
||||||
|
($code:literal, $disasm:literal) => {{
|
||||||
|
let ins = Ins::new($code, 0x8000_0000);
|
||||||
|
assert_eq!(format!("{}", FormattedIns(ins)), $disasm)
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -25,6 +29,13 @@ fn test_ins_addi() {
|
|||||||
assert_eq!(ins.defs(), vec![rD(GPR(0))]);
|
assert_eq!(ins.defs(), vec![rD(GPR(0))]);
|
||||||
assert_eq!(ins.uses(), vec![rA(GPR(1))]);
|
assert_eq!(ins.uses(), vec![rA(GPR(1))]);
|
||||||
assert_asm!(ins, "addi r0, r1, 0x140");
|
assert_asm!(ins, "addi r0, r1, 0x140");
|
||||||
|
|
||||||
|
assert_asm!(0x38010008, "addi r0, r1, 0x8");
|
||||||
|
assert_asm!(0x38010010, "addi r0, r1, 0x10");
|
||||||
|
assert_asm!(0x38010018, "addi r0, r1, 0x18");
|
||||||
|
assert_asm!(0x38010140, "addi r0, r1, 0x140");
|
||||||
|
assert_asm!(0x38049000, "addi r0, r4, -0x7000");
|
||||||
|
//assert_asm!(0x38a00000, "li r5, 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -45,48 +56,26 @@ fn test_ins_psq_lx() {
|
|||||||
assert_eq!(ins.uses(), vec![rB(GPR(0))]);
|
assert_eq!(ins.uses(), vec![rB(GPR(0))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_ins_addc() {
|
|
||||||
assert_asm!(0x7c002014, "addc r0, r0, r4");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ins_adde() {
|
fn test_ins_adde() {
|
||||||
assert_asm!(0x7c006114, "adde r0, r0, r12");
|
assert_asm!(0x7c006114, "adde r0, r0, r12");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_ins_addi() {
|
|
||||||
assert_asm!(0x38010008, "addi r0, r1, 0x8");
|
|
||||||
assert_asm!(0x38010010, "addi r0, r1, 0x10");
|
|
||||||
assert_asm!(0x38010018, "addi r0, r1, 0x18");
|
|
||||||
assert_asm!(0x38010140, "addi r0, r1, 0x140");
|
|
||||||
assert_asm!(0x38049000, "addi r0, r4, -28672");
|
|
||||||
assert_asm!(0x38a00000, "li r5, 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ins_addic() {
|
fn test_ins_addic() {
|
||||||
assert_asm!(0x3060ffff, "addic r3, r0, -1");
|
assert_asm!(0x3060ffff, "addic r3, r0, -0x1");
|
||||||
assert_asm!(0x30840800, "addic r4, r4, 0x800");
|
assert_asm!(0x30840800, "addic r4, r4, 0x800");
|
||||||
assert_asm!(0x30a50008, "addic r5, r5, 0x8");
|
assert_asm!(0x30a50008, "addic r5, r5, 0x8");
|
||||||
assert_asm!(0x37DF001C, "addic. r30, r31, 0x1c");
|
assert_asm!(0x37DF001C, "addic. r30, r31, 0x1c");
|
||||||
assert_asm!(0x37E06278, "addic. r31, r0, 0x6278");
|
assert_asm!(0x37E06278, "addic. r31, r0, 0x6278");
|
||||||
assert_asm!(0x37E3FFFF, "addic. r31, r3, -1");
|
assert_asm!(0x37E3FFFF, "addic. r31, r3, -0x1");
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_ins_addic_() {
|
|
||||||
assert_asm!(0x341D001C, "addic. r0, r29, 0x1c");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ins_addis() {
|
fn test_ins_addis() {
|
||||||
assert_asm!(0x3C030000, "addis r0, r3, 0");
|
assert_asm!(0x3C030000, "addis r0, r3, 0x0");
|
||||||
assert_asm!(0x3C038000, "addis r0, r3, 0x8000");
|
assert_asm!(0x3C038000, "addis r0, r3, 0x8000");
|
||||||
assert_asm!(0x3D00EFCE, "lis r8, 0xefce");
|
//assert_asm!(0x3D00EFCE, "lis r8, 0xefce");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -100,6 +89,8 @@ fn test_ins_and() {
|
|||||||
assert_asm!(0x7C001839, "and. r0, r0, r3");
|
assert_asm!(0x7C001839, "and. r0, r0, r3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ins_andc() {
|
fn test_ins_andc() {
|
||||||
assert_asm!(0x7C001878, "andc r0, r0, r3");
|
assert_asm!(0x7C001878, "andc r0, r0, r3");
|
||||||
|
@ -8,6 +8,12 @@ use serde::{Deserialize, Deserializer};
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use syn::LitInt;
|
use syn::LitInt;
|
||||||
|
|
||||||
|
macro_rules! token_stream {
|
||||||
|
($stream:ident) => {
|
||||||
|
TokenStream::from_iter($stream.into_iter())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct BitRange(Range<u8>);
|
pub(crate) struct BitRange(Range<u8>);
|
||||||
|
|
||||||
@ -159,9 +165,8 @@ impl Isa {
|
|||||||
#ident,
|
#ident,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.try_collect::<TokenStream, Vec<TokenStream>, syn::Error>()?
|
.try_collect::<TokenStream, Vec<TokenStream>, syn::Error>()?;
|
||||||
.into_iter();
|
let enum_variants = token_stream!(enum_variants);
|
||||||
let enum_variants = TokenStream::from_iter(enum_variants);
|
|
||||||
|
|
||||||
// Create functions.
|
// Create functions.
|
||||||
let mnemonic_fn = self.gen_mnemonic_fn()?;
|
let mnemonic_fn = self.gen_mnemonic_fn()?;
|
||||||
@ -194,12 +199,11 @@ impl Isa {
|
|||||||
Opcode::#variant => #literal,
|
Opcode::#variant => #literal,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.try_collect::<TokenStream, Vec<TokenStream>, syn::Error>()?
|
.try_collect::<TokenStream, Vec<TokenStream>, syn::Error>()?;
|
||||||
.into_iter();
|
let match_arms = token_stream!(match_arms);
|
||||||
let match_arms = TokenStream::from_iter(match_arms);
|
|
||||||
// Create final function.
|
// Create final function.
|
||||||
let mnemonic_fn = quote! {
|
let mnemonic_fn = quote! {
|
||||||
pub fn mnemonic(self) -> &'static str {
|
fn _mnemonic(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Opcode::Illegal => "<illegal>",
|
Opcode::Illegal => "<illegal>",
|
||||||
#match_arms
|
#match_arms
|
||||||
@ -226,12 +230,11 @@ impl Isa {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.try_collect::<TokenStream, Vec<TokenStream>, syn::Error>()?
|
.try_collect::<TokenStream, Vec<TokenStream>, syn::Error>()?;
|
||||||
.into_iter();
|
let if_chain = token_stream!(if_chain);
|
||||||
let if_chain = TokenStream::from_iter(if_chain);
|
|
||||||
// Generate function.
|
// Generate function.
|
||||||
let func = quote! {
|
let func = quote! {
|
||||||
pub fn detect(code: u32) -> Self {
|
fn _detect(code: u32) -> Self {
|
||||||
#if_chain
|
#if_chain
|
||||||
Opcode::Illegal
|
Opcode::Illegal
|
||||||
}
|
}
|
||||||
@ -247,7 +250,7 @@ impl Isa {
|
|||||||
enum_variants.push(field);
|
enum_variants.push(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let enum_variants = TokenStream::from_iter(enum_variants.into_iter());
|
let enum_variants = token_stream!(enum_variants);
|
||||||
|
|
||||||
// Create final enum.
|
// Create final enum.
|
||||||
let field_enum = quote! {
|
let field_enum = quote! {
|
||||||
@ -269,6 +272,7 @@ impl Isa {
|
|||||||
let mut field_match_arms = Vec::new();
|
let mut field_match_arms = Vec::new();
|
||||||
let mut def_match_arms = Vec::new();
|
let mut def_match_arms = Vec::new();
|
||||||
let mut use_match_arms = Vec::new();
|
let mut use_match_arms = Vec::new();
|
||||||
|
let mut modifier_match_arms = Vec::new();
|
||||||
for opcode in &self.opcodes {
|
for opcode in &self.opcodes {
|
||||||
// Generate fields of opcode.
|
// Generate fields of opcode.
|
||||||
// TODO Support mnemonics.
|
// TODO Support mnemonics.
|
||||||
@ -280,13 +284,39 @@ impl Isa {
|
|||||||
let variant = field.construct_variant_self();
|
let variant = field.construct_variant_self();
|
||||||
fields.extend(quote! { #variant, })
|
fields.extend(quote! { #variant, })
|
||||||
}
|
}
|
||||||
let fields = TokenStream::from_iter(fields.into_iter());
|
let fields = token_stream!(fields);
|
||||||
// Emit match arm.
|
// Emit match arm.
|
||||||
let ident = opcode.variant_identifier()?;
|
let ident = opcode.variant_identifier()?;
|
||||||
field_match_arms.push(quote! {
|
field_match_arms.push(quote! {
|
||||||
Opcode::#ident => vec![#fields],
|
Opcode::#ident => vec![#fields],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Generate modifiers.
|
||||||
|
let mut set_modifiers: Vec<TokenTree> = Vec::new();
|
||||||
|
for modifier in &opcode.modifiers {
|
||||||
|
set_modifiers.extend(match modifier.as_str() {
|
||||||
|
"OE" => quote! { m.oe = self.bit(21); },
|
||||||
|
"Rc" => quote! { m.rc = self.bit(31); },
|
||||||
|
"AA" => quote! { m.aa = self.bit(30); },
|
||||||
|
"LK" => quote! { m.lk = self.bit(31); },
|
||||||
|
_ => {
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
Span::call_site(),
|
||||||
|
format!("unsupported modifier {}", modifier),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let set_modifiers = token_stream!(set_modifiers);
|
||||||
|
modifier_match_arms.push(quote! {
|
||||||
|
Opcode::#ident => {
|
||||||
|
let mut m: Modifiers = std::default::Default::default();
|
||||||
|
#set_modifiers
|
||||||
|
m
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate defs.
|
||||||
let mut defs = Vec::new();
|
let mut defs = Vec::new();
|
||||||
for arg in &opcode.defs {
|
for arg in &opcode.defs {
|
||||||
let field: &Field = field_by_name.get(arg).ok_or_else(|| {
|
let field: &Field = field_by_name.get(arg).ok_or_else(|| {
|
||||||
@ -295,12 +325,13 @@ impl Isa {
|
|||||||
let variant = field.construct_variant_self();
|
let variant = field.construct_variant_self();
|
||||||
defs.extend(quote! { #variant, })
|
defs.extend(quote! { #variant, })
|
||||||
}
|
}
|
||||||
let defs = TokenStream::from_iter(defs.into_iter());
|
let defs = token_stream!(defs);
|
||||||
let ident = opcode.variant_identifier()?;
|
let ident = opcode.variant_identifier()?;
|
||||||
def_match_arms.push(quote! {
|
def_match_arms.push(quote! {
|
||||||
Opcode::#ident => vec![#defs],
|
Opcode::#ident => vec![#defs],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Generate uses.
|
||||||
let mut uses = Vec::new();
|
let mut uses = Vec::new();
|
||||||
let mut special_uses = Vec::new();
|
let mut special_uses = Vec::new();
|
||||||
for arg in &opcode.uses {
|
for arg in &opcode.uses {
|
||||||
@ -329,9 +360,9 @@ impl Isa {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let uses = TokenStream::from_iter(uses.into_iter());
|
let uses = token_stream!(uses);
|
||||||
let ident = opcode.variant_identifier()?;
|
let ident = opcode.variant_identifier()?;
|
||||||
let special_uses = TokenStream::from_iter(special_uses.into_iter());
|
let special_uses = token_stream!(special_uses);
|
||||||
use_match_arms.push(quote! {
|
use_match_arms.push(quote! {
|
||||||
Opcode::#ident => {
|
Opcode::#ident => {
|
||||||
let mut uses = vec![#uses];
|
let mut uses = vec![#uses];
|
||||||
@ -340,9 +371,10 @@ impl Isa {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let field_match_arms = TokenStream::from_iter(field_match_arms.into_iter());
|
let field_match_arms = token_stream!(field_match_arms);
|
||||||
let def_match_arms = TokenStream::from_iter(def_match_arms.into_iter());
|
let def_match_arms = token_stream!(def_match_arms);
|
||||||
let use_match_arms = TokenStream::from_iter(use_match_arms.into_iter());
|
let use_match_arms = token_stream!(use_match_arms);
|
||||||
|
let modifier_match_arms = token_stream!(modifier_match_arms);
|
||||||
// Generate final fields function.
|
// Generate final fields function.
|
||||||
let ins_impl = quote! {
|
let ins_impl = quote! {
|
||||||
impl Ins {
|
impl Ins {
|
||||||
@ -369,6 +401,14 @@ impl Isa {
|
|||||||
_ => todo!()
|
_ => todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _modifiers(&self) -> Modifiers {
|
||||||
|
match self.op {
|
||||||
|
Opcode::Illegal => std::default::Default::default(),
|
||||||
|
#modifier_match_arms
|
||||||
|
_ => todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(ins_impl)
|
Ok(ins_impl)
|
||||||
|
@ -204,7 +204,6 @@ opcodes:
|
|||||||
bitmask: 0xfc000000
|
bitmask: 0xfc000000
|
||||||
pattern: 0x3c000000
|
pattern: 0x3c000000
|
||||||
args: [ "rD", "rA", "uimm" ]
|
args: [ "rD", "rA", "uimm" ]
|
||||||
side_effects: [ "Rc" ]
|
|
||||||
defs: [ "rD" ]
|
defs: [ "rD" ]
|
||||||
uses: [ "rA.nz" ]
|
uses: [ "rA.nz" ]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user