Skip to content

Commit

Permalink
Add instruction listing functionality for aarch64, which also does a …
Browse files Browse the repository at this point in the history
…large amount of validation on the provided matcher-command infrastructure. Use it to validate matchers and commands.
  • Loading branch information
CensoredUsername committed Aug 17, 2019
1 parent c2331cf commit b23f891
Show file tree
Hide file tree
Showing 15 changed files with 708 additions and 160 deletions.
2 changes: 1 addition & 1 deletion build_docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mkdir ./build_docs/plugin
mkdir ./build_docs/runtime

echo "create instruction reference markdown file"
(cd doc/insref && cargo update && cargo run > ../instructionref.md)
(cd doc/insref && cargo update && cargo run -- x64 > ../instructionref_x64.md && cargo run -- aarch64 > ../instructionref_aarch64.md)

echo "build plugin docs"
for f in ./doc/*.md; do
Expand Down
11 changes: 10 additions & 1 deletion doc/insref/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@
use std::io::{self, Write};

fn main() {
let mut args = std::env::args();
args.next().unwrap();

let opmap = match args.next().expect("Architecture name").as_str() {
"x64" => dynasm::dynasm_opmap!(x64),
"aarch64" => dynasm::dynasm_opmap!(aarch64),
x => panic!("Unknown opmap format '{}'", x)
};

let stdout = io::stdout();
let mut stdout = stdout.lock();
stdout.write_all(dynasm::dynasm_opmap!().as_bytes()).unwrap();
stdout.write_all(opmap.as_bytes()).unwrap();
}
5 changes: 4 additions & 1 deletion doc/pre.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ <h3>Syntax</h3>
<a href="./langref.html">Language reference</a>
</li>
<li>
<a href="./instructionref.html">Instruction reference</a>
<a href="./instructionref_x64.html">Instruction reference (x64 and x86)</a>
</li>
<li>
<a href="./instructionref_aarch64.html">Instruction reference (aarch64)</a>
</li>
</ul>
</div>
Expand Down
10 changes: 6 additions & 4 deletions plugin/src/arch/aarch64/aarch64data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::common::Size;
use super::ast::Modifier;

use lazy_static::lazy_static;
use std::collections::HashMap;
use std::collections::{HashMap, hash_map};

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Matcher {
Expand Down Expand Up @@ -99,8 +99,6 @@ pub enum Command {
BUbits(u8), // checks if the pointed value fits in the given amount of bits
BSbits(u8), // checks if the pointed value fits in the given amount of bits
BUrange(u8, u8), // check if the pointed value is between min/max
BUscaled(u8, u8), // check if the pointed value fits in .0 bits, after being shifted .1 bits to the right
BSscaled(u8, u8), // check if the pointed value fits in .0 bits, after being shifted .1 bits to the right
Uslice(u8, u8, u8), // encodes at .0, .1 bits long, the bitslice starting at .2 from the current arg
Sslice(u8, u8, u8), // encodes at .0, .1 bits long, the bitslice starting at .2 from the current arg

Expand Down Expand Up @@ -130,7 +128,6 @@ pub enum Command {
// special commands
A, // advances the argument pointer, only needed to skip over an argument.
C, // moves the argument pointer back.
Static(u8, u32) // just insert these bits at this location.
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -228,6 +225,11 @@ pub fn get_mnemonic_data(name: &str) -> Option<&'static [Opdata]> {
OPMAP.get(&name).cloned()
}

#[allow(dead_code)]
pub fn mnemnonics() -> hash_map::Keys<'static, &'static str, &'static [Opdata]> {
OPMAP.keys()
}

lazy_static! {
static ref OPMAP: HashMap<&'static str, &'static [Opdata]> = {
let mut map = HashMap::new();
Expand Down
65 changes: 1 addition & 64 deletions plugin/src/arch/aarch64/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,28 +142,12 @@ impl PartialEq<RegKind> for RegKind {
}

impl RegScalar {
pub fn new_static(size: Size, id: RegId) -> RegScalar {
RegScalar {size, kind: RegKind::Static(id) }
}

pub fn new_dynamic(size: Size, family: RegFamily, id: syn::Expr) -> RegScalar {
RegScalar {size, kind: RegKind::Dynamic(family, id) }
}

pub fn size(&self) -> Size {
self.size
}
}

impl RegVector {
pub fn new_static(id: RegId, element_size: Size, lanes: Option<u8>, element: Option<syn::Expr>) -> RegVector {
RegVector {kind: RegKind::Static(id), element_size, lanes, element}
}

pub fn new_dynamic(id: syn::Expr, element_size: Size, lanes: Option<u8>, element: Option<syn::Expr>) -> RegVector {
RegVector {kind: RegKind::Dynamic(RegFamily::SIMD, id), element_size, lanes, element}
}

/// Returns the size of individual elements in this vector register
pub fn element_size(&self) -> Size {
self.element_size
Expand Down Expand Up @@ -209,33 +193,12 @@ impl Register {
}
}

pub fn is_dynamic(&self) -> bool {
match self {
Register::Scalar(s) => s.kind.is_dynamic(),
Register::Vector(v) => v.kind.is_dynamic()
}
}

pub fn is_vector(&self) -> bool {
match self {
Register::Scalar(_) => false,
Register::Vector(_) => true
}
}

pub fn assume_vector(&self) -> &RegVector {
match self {
Register::Scalar(_) => panic!("That wasn't a vector register"),
Register::Vector(v) => v
}
}

pub fn assume_scalar(&self) -> &RegScalar {
match self {
Register::Scalar(s) => s,
Register::Vector(_) => panic!("That wasn't a scalar register"),
}
}
}

/**
Expand Down Expand Up @@ -274,30 +237,6 @@ impl ModifyExpr {
}
}

/**
* Condition codes
*/

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Condition {
EQ,
NE,
CS,
CC,
MI,
PL,
VS,
VC,
HI,
LS,
GE,
LT,
GT,
LE,
AL,
NV,
}

/**
* Memory ref item types
*/
Expand Down Expand Up @@ -371,9 +310,7 @@ pub enum RawArg {
// an ident, not intended to be parsed as an expression
Lit {
ident: syn::Ident
},
// used to not block the parser on a parsing error in a single arg
Invalid
}
}

// Contains the actual instruction mnemnonic.
Expand Down
25 changes: 2 additions & 23 deletions plugin/src/arch/aarch64/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ pub(super) fn compile_instruction(ctx: &mut Context, data: MatchData) -> Result<
cursor -= 1;
continue
},
Command::Static(offset, staticbits) => {
statics.push((offset, staticbits));
continue
},
Command::Rwidth(offset) => {
statics.push((offset, data.simd_full_width.unwrap_or(true) as u32));
continue
Expand Down Expand Up @@ -302,19 +298,6 @@ pub(super) fn compile_instruction(ctx: &mut Context, data: MatchData) -> Result<
value?;
}
},
Command::BUscaled(bitlen, shift) => {
let mask = bitmask(bitlen);
if let Some(value) = unsigned_rangecheck(value, 0, mask, shift) {
value?;
}
},
Command::BSscaled(bitlen, shift) => {
let mask = bitmask(bitlen);
let half = -1i32 << (bitlen - 1);
if let Some(value) = signed_rangecheck(value, half, mask as i32 + half, shift) {
value?;
}
},

// specials. These have some more involved code.
Command::Special(offset, special) => handle_special_immediates(offset, special, value, &mut statics, &mut dynamics)?,
Expand Down Expand Up @@ -351,9 +334,7 @@ pub(super) fn compile_instruction(ctx: &mut Context, data: MatchData) -> Result<

// integer checks don't have anything to check
Command::BUbits(_) |
Command::BSbits(_) |
Command::BUscaled(_, _) |
Command::BSscaled(_, _) => (),
Command::BSbits(_) => (),

_ => panic!("Invalid argument processor")
},
Expand Down Expand Up @@ -402,9 +383,7 @@ pub(super) fn compile_instruction(ctx: &mut Context, data: MatchData) -> Result<
Command::Sslice(_, _, _) => (),
Command::BUbits(_) |
Command::BSbits(_) |
Command::BUrange(_, _) |
Command::BUscaled(_, _) |
Command::BSscaled(_, _) => (),
Command::BUrange(_, _) => (),
_ => cursor += 1
}
}
Expand Down
Loading

0 comments on commit b23f891

Please sign in to comment.