Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2ed6200
Add initial imm attribute support
zero318 Jun 29, 2022
a8b2ad4
Improve unsigned/hex support and update padding
zero318 Jun 30, 2022
e66c92d
Several suggested changes
zero318 Jun 30, 2022
f3de737
Change _ back to 4 bytes and add - for single bytes
zero318 Jun 30, 2022
96c1d4c
First batch of updated signatures
zero318 Jul 1, 2022
7fe31f4
Second batch of updated signatures
zero318 Jul 2, 2022
4d089ac
Add scratch registers for IN-StB and fix size arg sign
zero318 Jul 2, 2022
9605ae3
Third batch of updated signatures
zero318 Jul 3, 2022
5ff6724
Fourth batch of updated signatures
zero318 Jul 5, 2022
b3e8508
please let the merge work
zero318 Jul 5, 2022
b70b2ed
Fifth batch of updated signatures
zero318 Jul 7, 2022
17ce209
Sixth batch of updated signatures
zero318 Jul 9, 2022
92292d5
Seventh batch of updated signatures
zero318 Jul 10, 2022
3d32e3b
Eigth batch of updated signatures
zero318 Jul 12, 2022
88e5a47
Ninth batch of updated signatures and a few misc fixes
zero318 Jul 15, 2022
26f14dc
e
zero318 Apr 26, 2024
6e5e625
Fixed roundtrip problems
zero318 Apr 27, 2024
8d9e7a8
First attempt at th20 support
zero318 May 5, 2025
7a8dd56
Fix th20 std support
khang06 May 5, 2025
4e2e6a2
Merge pull request #2 from khang06/th20-std
zero318 May 5, 2025
ac21a91
Fix th20 std support (again)
khang06 Aug 25, 2025
fba8534
Merge pull request #3 from khang06/th20-std
zero318 Aug 25, 2025
e04f291
Fix more STD/MSG/END stuff for th20
zero318 Aug 25, 2025
20a4da0
Merge commit '7517af7ac0352ae0f42d0b998f46af7946521e9e' into neww-zero
ExpHP Aug 26, 2025
b2dcd1c
Merge commit '88e5a47a2f9bbdd5fdc999bec32999350faf59c' into neww-zero
ExpHP Aug 26, 2025
7778c45
e
zero318 Apr 26, 2024
21c30dd
Fixed roundtrip problems
zero318 Apr 27, 2024
3bdc5fa
First attempt at th20 support
zero318 May 5, 2025
e9c3d28
Fix th20 std support
khang06 May 5, 2025
471b51d
Fix th20 std support (again)
khang06 Aug 25, 2025
1a5964e
Fix more STD/MSG/END stuff for th20
zero318 Aug 25, 2025
8eb4c4b
Merge branch 'format_improvements_test' of https://github.com/ExpHP/t…
zero318 Aug 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/core_mapfiles/ecl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ static ECL_08_09: &'static CoreSignatures = &CoreSignatures {
(Th08, 127, Some(("S", None))),
(Th08, 128, Some(("S(imm)f(imm)f(imm)f(imm)f(imm)", None))), // Argument 1 is unread
(Th08, 129, Some(("b(imm)---", None))),
(Th08, 130, Some((r#"s(imm;enum="EclSub")--"#, None))),
(Th08, 130, Some((r#"s(imm;extend;enum="EclSub")--"#, None))),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"extend" is too short of a name for something that is probably only ever going to be used once. Probably want something with multiple words, meaning we might need to pick now whether we want snake_case or kebab-case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There're quite a few places where the game engines will read a full dword from the signature in order to check for variables but then only read the lower bits of the resulting value. Ideally extend could be replaced with a more general purpose attribute applicable to those situations as well since that would eliminate the need for extended padding anyway. Maybe this could be written as E(imm;range="s") or something?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was also thinking this should probably be a dword-sized value with an attribute that limits its value size. However, I really do not want to see abi letters get used inside string literals.

(Th08, 131, Some(("S", None))),
(Th08, 132, Some(("S", None))),
(Th08, 133, Some(("SSE", None))),
Expand Down Expand Up @@ -903,7 +903,7 @@ static ECL_095: &'static CoreSignatures = &CoreSignatures {
(Th095, 81, Some(("U(hex)", None))),
(Th095, 82, Some(("f", None))),
(Th095, 83, Some(("E(imm)", None))),
(Th095, 84, Some(("E(imm)fff", None))),
(Th095, 84, Some(("E(imm)ff", None))), // Game engine reads E(imm)fff, but the files are cursed trash
(Th095, 85, Some(("", None))),
(Th095, 86, Some(("ssSSffffU(imm;hex)", None))),
(Th095, 87, Some(("ssSSffffU(imm;hex)", None))),
Expand Down Expand Up @@ -1088,6 +1088,7 @@ static ECL_10_11: &'static CoreSignatures = &CoreSignatures {

(Th11, 276, Some(("", None))),
(Th11, 277, Some(("Sf", None))),
(Th11, 278, Some(("S", None))), // Not implemented

// Section B
(Th10, 280, Some(("ff", None))),
Expand Down Expand Up @@ -1243,6 +1244,11 @@ static ECL_10_11: &'static CoreSignatures = &CoreSignatures {
(Th11, 448, Some(("S", None))),
(Th11, 449, Some(("S", None))),
(Th11, 450, Some(("S", None))),

// Section E (Didn't exist yet)

// Section F
(Th11, 500, Some(("S", None))), // Not implemented
],
var: &[
// This is placed here to avoid putting game-specific
Expand Down Expand Up @@ -1313,6 +1319,10 @@ static ECL_12: &'static CoreSignatures = &CoreSignatures {
(Th12, 325, Some(("Sffffff", None))),
(Th12, 326, Some(("Sffffff", None))),
(Th12, 327, Some(("", None))),
(Th12, 328, Some(("ff", None))),
(Th12, 329, Some(("SSff", None))),
(Th12, 330, Some(("ff", None))),
(Th12, 331, Some(("SSff", None))),

// Section C
(Th12, 400, Some(("ff", None))),
Expand Down Expand Up @@ -1430,7 +1440,7 @@ static ECL_12: &'static CoreSignatures = &CoreSignatures {
(Th12, 611, Some(("S", None))),

// Section F
(Th12, 700, Some(("S", None))),
(Th12, 700, Some(("S", None))), // Not implemented
],
var: &[],
};
Expand Down
2 changes: 2 additions & 0 deletions src/core_mapfiles/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ static MSG_10_18: &CoreSignatures = &CoreSignatures {
(Th12, 17, Some(("m(bs=4;mask=0x77,7,16;furibug)", None))),
(Th12, 27, Some(("f", None))), // new

(Th128, 2, Some(("S", None))), // Argument started being non-zero
(Th128, 28, Some(("ff", None))),
(Th128, 29, Some(("S", None))),
(Th128, 30, Some(("", None))),
Expand All @@ -143,6 +144,7 @@ static MSG_10_18: &CoreSignatures = &CoreSignatures {

(Th15, 33, None), // removed

(Th16, 1, Some(("S", None))), // Argument started being non-zero
(Th16, 33, Some(("SS", None))), // replaced with something totally different (but unused)
(Th16, 34, Some(("SS", None))),
(Th16, 35, Some(("", None))),
Expand Down
6 changes: 2 additions & 4 deletions src/core_mapfiles/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ static STD_095_18: &CoreSignatures = &CoreSignatures {
(Th095, 7, Some(("f", None))),
(Th095, 8, Some(("Cff", None))),
(Th095, 9, Some(("Sbb--Cff", None))),
(Th095, 10, Some(("SUfffffffff", None))),
(Th095, 11, Some(("SUfffffffff", None))),
(Th095, 10, Some(("SUfffffffff", None))), // Technically S_fffffffff since MoF
(Th095, 11, Some(("SUfffffffff", None))), // Technically S_fffffffff since MoF
(Th095, 12, Some(("b---", None))),
(Th095, 13, Some(("C", None))),
(Th095, 14, Some(("SN", None))),
Expand All @@ -96,8 +96,6 @@ static STD_095_18: &CoreSignatures = &CoreSignatures {
(Th10, 3, Some(("SUfff", None))),
(Th10, 5, Some(("SUfff", None))),
(Th10, 9, Some(("SUCff", None))), // Technically the C arg is split into 4 individual byte reads. But why tho
(Th10, 10, Some(("S_fffffffff", None))),
(Th10, 11, Some(("S_fffffffff", None))),

(Alcostg, 16, Some(("S(imm)", Some(IKind::InterruptLabel)))),

Expand Down
4 changes: 2 additions & 2 deletions src/formats/anm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,7 @@ fn strip_unnecessary_sprite_ids<'a>(entry_sprites: impl IntoIterator<Item=&'a mu
if actual_id == next_auto_sprite_id {
sprite.id = None;
}
next_auto_sprite_id = actual_id + 1;
next_auto_sprite_id = actual_id.wrapping_add(1);
}
}
}
Expand All @@ -1165,7 +1165,7 @@ fn all_sprite_ids<'a>(entry_sprites: impl IntoIterator<Item=&'a IndexMap<Sp<Iden
for sprites in entry_sprites {
for sprite in sprites.values() {
let actual_id = sprite.id.unwrap_or(next_auto_sprite_id);
next_auto_sprite_id = actual_id + 1;
next_auto_sprite_id = actual_id.wrapping_add(1);
out.push(actual_id);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/formats/anm/read_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ fn write_entry(
let sprite_offset = w.pos()? - entry_pos;

let sprite_id = sprite.id.unwrap_or(*next_auto_sprite_id);
*next_auto_sprite_id = sprite_id + 1;
*next_auto_sprite_id = sprite_id.wrapping_add(1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ZUN did something extremely cursed in a few old engine files and uses -1 as the sprite ID to intentionally overwrite sprites from a different ANM. This didn't break previously because truth didn't dump the ID field to roundtrip it but blew up once the field was added.


write_sprite(w, sprite_id, sprite)?;
Ok(sprite_offset)
Expand Down
12 changes: 7 additions & 5 deletions src/llir/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub enum ArgEncoding {
/// The first argument may have `arg0` if it is two bytes large. This indicates that the argument is
/// stored in the arg0 header field of the instruction in EoSD and PCB ECL. (which is mapped to the
/// `@arg0` pseudo-argument in raw instruction syntax)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document extend.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What sort of formatting should be used for that? The only currently documented attributes are mask and furibug, which don't even use the same format.

Copy link
Owner

@ExpHP ExpHP Jul 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh bugger, I forgot to document enum. That's the only thing I see missing from here.

It should be in prose in the documentation of Integer, just like the documentation for arg0 that I put this review comment under. (basically, "put it here!")

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, imm is also missing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And hex isn't included either. There're enough attributes that there should probably be a list with the names at the front.

Copy link
Owner

@ExpHP ExpHP Jul 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we probably want to make a markdown list

///
/// Supported attributes:
///
/// * **`imm`**: lorem ipsum dolor sit amet
/// i have a barnicle in my backseat
/// * **`arg0`**: blah blah blah blah

etc

Integer { size: u8, ty_color: Option<TypeColor>, arg0: bool, immediate: bool, format: ast::IntFormat },
Integer { size: u8, ty_color: Option<TypeColor>, arg0: bool, immediate: bool, extend: bool, format: ast::IntFormat },
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is getting out of hand, let's break this up over lines.

/// `o` in mapfile. Max of one per instruction. Is decoded to a label.
JumpOffset,
/// `t` in mapfile. Max of one per instruction, and requires an accompanying `o` arg.
Expand Down Expand Up @@ -91,7 +91,7 @@ pub enum StringArgSize {
}

impl ArgEncoding {
pub fn dword() -> Self { ArgEncoding::Integer { size: 4, ty_color: None, arg0: false, immediate: false, format: ast::IntFormat { unsigned: false, radix: ast::IntRadix::Dec } } }
pub fn dword() -> Self { ArgEncoding::Integer { size: 4, ty_color: None, arg0: false, immediate: false, extend: false, format: ast::IntFormat { unsigned: false, radix: ast::IntRadix::Dec } } }

pub fn static_descr(&self) -> &'static str {
match self {
Expand All @@ -115,10 +115,10 @@ impl ArgEncoding {
impl fmt::Display for Impl<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.0 {
Enc::Integer { arg0: true, ty_color, size, immediate, format } => write!(
Enc::Integer { arg0: true, ty_color, size, immediate, format, extend } => write!(
f,
"{} (in timeline arg0)",
Enc::Integer { format: *format, immediate: *immediate, arg0: false, ty_color: ty_color.clone(), size: *size }.descr(),
Enc::Integer { extend: *extend, format: *format, immediate: *immediate, arg0: false, ty_color: ty_color.clone(), size: *size }.descr(),
),
Enc::Integer { ty_color: Some(en), size: 4, .. } => write!(f, "{}", en.descr()),
Enc::Integer { ty_color: Some(en), size, .. } => write!(f, "{size}-byte {}", en.descr()),
Expand Down Expand Up @@ -275,6 +275,7 @@ fn int_from_attrs(param: &abi_ast::Param, emitter: &dyn Emitter) -> Result<Optio
let arg0 = de.accept_flag("arg0")?;
let imm = de.accept_flag("imm")?;
let is_hex = de.accept_flag("hex")?;
let extend = de.accept_flag("extend")?;

if let Some(arg0_flag) = arg0 {
if size.wrapping_sub(1) >= 2 {
Expand All @@ -299,6 +300,7 @@ fn int_from_attrs(param: &abi_ast::Param, emitter: &dyn Emitter) -> Result<Optio
ty_color: user_ty_color.or(default_ty_color),
arg0: arg0.is_some(),
immediate: imm.is_some(),
extend: extend.is_some(),
format: ast::IntFormat { unsigned, radix },
}))
})
Expand Down Expand Up @@ -424,7 +426,7 @@ fn abi_to_signature(abi: &InstrAbi, abi_span: Span, ctx: &mut CompilerContext<'_

defs::Signature {
return_ty: sp!(value::ExprType::Void),
params: abi.encodings.iter().enumerate().flat_map(|(index, enc)| {
params: abi.encodings.iter().filter(|enc| !matches!(*enc, ArgEncoding::Padding { .. })).enumerate().flat_map(|(index, enc)| {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is too noisy. Funnily, this is a flat_map and yet it doesn't even look like anything is currently taking advantage of that; but this is exactly the sort of use case for that, so let's make use of it:

Suggested change
params: abi.encodings.iter().filter(|enc| !matches!(*enc, ArgEncoding::Padding { .. })).enumerate().flat_map(|(index, enc)| {
params: abi.encodings.iter().enumerate().flat_map(|(index, enc)| {

And change the Padding match arm to:

                | ArgEncoding::Padding { .. }
                => return None,  // hide from signature

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was concerned something like that would end up inserting a None into the resulting collection. Didn't know it would skip over it. Seems like there could be issues in the future though if index is ever used for anything though.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops I missed the fact that this would change indices, lemme read this over again.

Copy link
Owner

@ExpHP ExpHP Jul 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was concerned something like that would end up inserting a None into the resulting collection.

flat_map flattens the iterators being returned by the closures. Option is an iterator of zero or one items, so None produces no items. Technically, this should be using .filter_map instead (you can just change the .flat_map to .filter_map and it should still compile); this is just an alias for Option-based flat_maps that is clearer in intent.

Oops I missed the fact that this would change indices, lemme read this over again.

So the index is only used to generate arg names. I would pull that out.

// in a line of code outside the loop
let arg_names = (1..).map(|i| ident!("arg_{i}"));

// inside the loop, change this line:
let name = sp!(abi_span => ctx.resolutions.attach_fresh_res(arg_names.next().unwrap()));

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and of course get rid of the enumerate()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make more sense to just add another function to the InstrAbi implementation similar to arg_encodings that returns the filtered version? This seems like the sort of thing that would end up continually popping up throughout the code base otherwise. (I would've done that in the first place, but rust complained about the filter output not being compatible with VeclikeIterator or something and I don't know how to make it happy.)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmmm. Crap, that's a pain.

Writing this function is probably a good idea. It will have to return the slightly weaker DoubleEndedIterator instead of VeclikeIterator. (basically because filter can't be ExactSizeIterator, which is the other half of VeclikeIterator)

let Info { ty, default, reg_ok, ty_color } = match *enc {
| ArgEncoding::Integer { arg0: false, ref ty_color, .. }
=> Info { ty: ScalarType::Int, default: None, reg_ok: true, ty_color: ty_color.clone() },
Expand Down
33 changes: 27 additions & 6 deletions src/llir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,18 +554,25 @@ fn encode_args(
let mut param_mask: raw::ParamMask = 0;
let mut current_param_mask_bit: raw::ParamMask = 1;

let mut small_padding_value = 0i8;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to see tests for:

  • basic functionality of extend
  • padding value resetting to 0 at dword boundaries. (s(extend)------)
  • resetting to zero on positive values

That last one would involve

10 s(extend)b-
ins_10(-2, 1)

args_blob should compile to blobify![-2i16, 1i16]. You will need to impl Blobify for i16 here:

impl Blobify for i32 {
(frankly this should probably be using a macro to gen impls for all integer types)


// Important: we put the shortest iterator (args_iter) first in the zip list
// to ensure that this loop reads an equal number of items from all iters.
assert!(args_iter.len() <= arg_encodings_iter.len());
for enc in arg_encodings_iter.by_ref() {
if let ArgEncoding::Padding { size } = enc {
match size {
1 => args_blob.write_u8(0).expect("Cursor<Vec> failed?!"),
1 => {
if (args_blob.position() & 3) == 0 { small_padding_value = 0i8 }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid one-line ifs. I reserve these for extreme cases (usually only when there are multiple similar ifs in a row and I want to emphasize the similarities between them)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll freely admit the entire logic for handling that was a 5 minute quick fix that bolts a random functionality where it doesn't quite belong. I'd love to replace the logic with something better that doesn't feel as dirty.

Copy link
Owner

@ExpHP ExpHP Jul 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the complexity of this function increases (which it is no doubt going to, without end), we're going to want to start factoring out pieces of it into separable units.

This thing right here is easily separated out into a Finite State Machine. You could have something like:

/// Finite-state machine helper for the value of `-` padding.
struct SmallPaddingFillHelper {
    fill_value: i8,
}

impl SmallPaddingFillHelper {
    /// Update the helper in response to the next arg encoding.
    ///
    /// Returns the current fill value for `-` padding.
    fn step(&mut self, enc: &ArgEncoding, blob_position: u64) -> i8 {
        todo!("update self.fill_value");
        self.fill_value
    }
}

and then you could put let small_padding_fill = padding_helper.step(enc, args_blob.position()); near the top of the loop

Copy link
Contributor Author

@zero318 zero318 Jul 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant more that I'd rather leave the padding bytes as exclusively 0, eliminate the padding fill variable entirely, and let the values be handled by a range sort of attribute within a single larger value. That way there isn't any more multi-iteration mutable state than there needs to be.

args_blob.write_i8(small_padding_value).expect("Cursor<Vec> failed?!")
},
4 => args_blob.write_u32(0).expect("Cursor<Vec> failed?!"),
_ => unreachable!(),
}
continue;
}
small_padding_value = 0i8;

let arg = args_iter.next().expect("function arity already checked");

let arg_bit = match &arg.value {
Expand Down Expand Up @@ -607,14 +614,28 @@ fn encode_args(

| ArgEncoding::JumpOffset
| ArgEncoding::JumpTime
| ArgEncoding::Integer { size: 4, format: ast::IntFormat { unsigned: false, radix: _ }, .. }
=> args_blob.write_i32(arg.expect_raw().expect_int()).expect("Cursor<Vec> failed?!"),

| ArgEncoding::Integer { size: 2, format: ast::IntFormat { unsigned: false, radix: _ }, .. }
=> args_blob.write_i16(arg.expect_raw().expect_int() as _).expect("Cursor<Vec> failed?!"),
| ArgEncoding::Integer { size: 4, extend, format: ast::IntFormat { unsigned: false, radix: _ }, .. }
=> {
let value = arg.expect_raw().expect_int();
if extend && value < 0 { small_padding_value = -1 }
args_blob.write_i32(value).expect("Cursor<Vec> failed?!")
},

| ArgEncoding::Integer { size: 1, format: ast::IntFormat { unsigned: false, radix: _ }, .. }
=> args_blob.write_i8(arg.expect_raw().expect_int() as _).expect("Cursor<Vec> failed?!"),
| ArgEncoding::Integer { size: 2, extend, format: ast::IntFormat { unsigned: false, radix: _ }, .. }
=> {
let value = arg.expect_raw().expect_int();
if extend && value < 0 { small_padding_value = -1 }
args_blob.write_i16(value as _).expect("Cursor<Vec> failed?!")
},

| ArgEncoding::Integer { size: 1, extend, format: ast::IntFormat { unsigned: false, radix: _ }, .. }
=> {
let value = arg.expect_raw().expect_int();
if extend && value < 0 { small_padding_value = -1 }
args_blob.write_i8(value as _).expect("Cursor<Vec> failed?!")
},

| ArgEncoding::Integer { size: 4, format: ast::IntFormat { unsigned: true, radix: _ }, .. }
=> args_blob.write_u32(arg.expect_raw().expect_int() as _).expect("Cursor<Vec> failed?!"),
Expand Down
2 changes: 1 addition & 1 deletion src/llir/raise/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ impl AtomRaiser<'_, '_> {
let pseudo_arg0 = match instr.pseudo_arg0 {
None | Some(0) => None,
Some(arg0) => {
let enc = ArgEncoding::Integer { size: 2, ty_color: None, arg0: true, immediate: true, format: ast::IntFormat { unsigned: false, radix: ast::IntRadix::Dec } };
let enc = ArgEncoding::Integer { size: 2, ty_color: None, arg0: true, immediate: true, extend: false, format: ast::IntFormat { unsigned: false, radix: ast::IntRadix::Dec } };
let expr = self.raise_arg(emitter, &SimpleArg::from(arg0 as i32), &enc, dest_label)?;
Some(expr)
}
Expand Down