summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-10-11 18:27:48 -0700
committeriximeow <me@iximeow.net>2020-10-11 18:27:48 -0700
commitef761196ae6666f2c8067370d28a1d270ed7f666 (patch)
tree63cb3228c1df7f2b14709df4294c336eec2ec9f3
parent37617948420982554928e4ba3213f489c2f5054e (diff)
fix reversed l/x instruction word order and immediate decode
-rw-r--r--src/lib.rs46
-rw-r--r--tests/test.rs9
2 files changed, 39 insertions, 16 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 75b75a7..1f46031 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1261,17 +1261,24 @@ impl Default for InstructionBundle {
}
impl fmt::Display for InstructionBundle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let stops = if let Some((types, stops)) = BUNDLE_TAGS[self.bundle_tag as usize] {
+ let (stops, types) = if let Some((types, stops)) = BUNDLE_TAGS[self.bundle_tag as usize] {
write!(f, "[{}{}{}]", types[0], types[1], types[2])?;
- [(stops & 0b100) > 0, (stops & 0b010) > 0, (stops & 0b001) > 0]
+ ([(stops & 0b100) > 0, (stops & 0b010) > 0, (stops & 0b001) > 0], types)
} else {
return write!(f, "tag: invalid ({})", self.bundle_tag);
};
- write!(f, " {}{}; {}{}; {}{}",
- &self.instructions[0], if stops[0] { ";" } else { "" },
- &self.instructions[1], if stops[1] { ";" } else { "" },
- &self.instructions[2], if stops[2] { ";;" } else { "" },
- )
+ if types[2] == InstructionType::X {
+ write!(f, " {}{}; {}{}",
+ &self.instructions[0], if stops[0] { ";" } else { "" },
+ &self.instructions[1], if stops[1] { ";;" } else { "" },
+ )
+ } else {
+ write!(f, " {}{}; {}{}; {}{}",
+ &self.instructions[0], if stops[0] { ";" } else { "" },
+ &self.instructions[1], if stops[1] { ";" } else { "" },
+ &self.instructions[2], if stops[2] { ";;" } else { "" },
+ )
+ }
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -1594,7 +1601,7 @@ impl Decoder<InstructionBundle> for InstDecoder {
];
let (instruction_types, stop_mask) = BUNDLE_TAGS[bundle_tag as usize].ok_or(DecodeError::BadBundle)?;
- fn decode_l_instruction(word: &BitSlice<Lsb0, u8>, word2: &BitSlice<Lsb0, u8>) -> Instruction {
+ fn decode_l_instruction(word2: &BitSlice<Lsb0, u8>, word: &BitSlice<Lsb0, u8>) -> Instruction {
let tag = word[37..41].load::<u8>();
let (opcode, operand_encoding) = get_l_opcode_and_encoding(tag, word);
@@ -1867,12 +1874,19 @@ fn read_l_operands(encoding: OperandEncodingX, word: &BitSlice<Lsb0, u8>, word2:
X2 => {
let r1 = word[6..13].load::<u8>();
let imm7b = word[13..20].load::<u64>();
- let ic = word[21];
- let immdc = word[22..36].load::<u64>();
- let i = word[36];
+ let ic = word[21] as u64;
+ let immd = word[27..36].load::<u64>();
+ let immc = word[22..27].load::<u64>();
+ let i = word[36] as u64;
let imm41 = word2[0..41].load::<u64>();
- // TODO: this is certainly assembled incorrectly
- let imm = (imm41 << 21) + ((i as u64) << 20) + imm7b + immdc + (ic as u64);
+ // TODO: might be right, i, c, and imm41 may be mixed up.
+ let imm =
+ imm7b +
+ (immd << 7) +
+ (immc << 16) +
+ (i << 21) +
+ (ic << 22) +
+ (imm41 << 23);
two_op(
Some(0),
Operand::GPRegister(GPRegister(r1)),
@@ -2416,8 +2430,8 @@ fn read_i_operands(encoding: OperandEncodingI, word: &BitSlice<Lsb0, u8>) -> (Op
let r1 = word[6..13].load::<u8>();
let r2 = word[13..20].load::<u8>();
let r3 = word[20..27].load::<u8>();
- let len = word[27..31].load::<u8>();
- let cpos = word[31..37].load::<u8>();
+ let len = word[27..31].load::<u8>() + 1;
+ let cpos = 63 - word[31..37].load::<u8>(); // not sure if this is accurate? makes the dep r14=r18 test pass...
(
Some(0),
[
@@ -2905,8 +2919,8 @@ fn read_a_operands(encoding: OperandEncodingA, word: &BitSlice<Lsb0, u8>) -> (Op
three_op(
Some(0),
Operand::GPRegister(GPRegister(r1)),
- Operand::GPRegister(GPRegister(r3)),
Operand::ImmI64(imm as i64),
+ Operand::GPRegister(GPRegister(r3)),
)
},
A4 => {
diff --git a/tests/test.rs b/tests/test.rs
index 686d94b..24a1937 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -11,6 +11,15 @@ fn test_addl_imm() {
assert_eq!(format!("{}", inst), expected);
}
#[test]
+fn test_mlx_bundle() {
+ let decoder = InstDecoder::default();
+
+ let expected = "[MLX] alloc r34=ar.pfs,5,5,0; movl r32=0xfffffffffffff5f8;;";
+ let data = [0x05, 0x10, 0x15, 0x0a, 0x80, 0xc5, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x84, 0xf7, 0xaf, 0x6f];
+ let inst = decoder.decode(data[..].iter().cloned()).unwrap();
+ assert_eq!(format!("{}", inst), expected);
+}
+#[test]
fn test_a_bundle() {
// from elf64-ia64-vms.c
// [MMI] addl r15=0,r1;;