Skip to content

Commit d57161d

Browse files
committed
Perlito5::X64::Assembler - add cpuid, neg, leave, int3
1 parent 84ad906 commit d57161d

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src5/lib/Perlito5/X64/Assembler.pm

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,18 @@ sub emit_rex_64 {
197197
}
198198
}
199199

200-
# Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
201200
sub emit_modrm {
202201
my ($reg, $rm_reg) = @_;
203202
if ( is_register($reg) && is_register($rm_reg) ) {
203+
# Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
204204
emit(0xC0 | $reg->low_bits() << 3 | $rm_reg->low_bits());
205205
}
206+
elsif ( is_register($rm_reg) ) {
207+
# Emit a ModR/M byte with an operation subcode in the reg field and
208+
# a register in the rm_reg field.
209+
my ($code, $rm_reg) = @_;
210+
emit(0xC0 | $code << 3 | $rm_reg->low_bits());
211+
}
206212
else {
207213
die "emit_modrm: don't know what to do with $reg, $rm_reg";
208214
}
@@ -255,6 +261,24 @@ sub _bind {
255261
$label->bind( scalar(@buffer) );
256262
}
257263

264+
sub _cpuid {
265+
emit(0x0F);
266+
emit(0xA2);
267+
}
268+
269+
sub _cqo {
270+
emit_rex_64();
271+
emit(0x99);
272+
}
273+
274+
sub _hlt {
275+
emit(0xF4);
276+
}
277+
278+
sub _int3 {
279+
emit(0xCC);
280+
}
281+
258282
sub _jmp {
259283
my ( $label, $distance ) = @_;
260284

@@ -279,6 +303,10 @@ sub _jmp {
279303
}
280304
}
281305

306+
sub _leave {
307+
emit(0xC9);
308+
}
309+
282310
sub _movl {
283311
my ( $dst, $src ) = @_;
284312
if ( is_register($dst) && is_register($src) ) {
@@ -351,6 +379,27 @@ sub _repmovsq() {
351379
emit(0xA5);
352380
}
353381

382+
sub _mul {
383+
my ($src) = @_;
384+
emit_rex_64($src);
385+
emit(0xF7);
386+
emit_modrm( 0x4, $src );
387+
}
388+
389+
sub _neg {
390+
my ($dst) = @_;
391+
emit_rex_64($dst);
392+
emit(0xF7);
393+
emit_modrm( 0x3, $dst );
394+
}
395+
396+
sub _negl {
397+
my ($dst) = @_;
398+
emit_optional_rex_32($dst);
399+
emit(0xF7);
400+
emit_modrm( 0x3, $dst );
401+
}
402+
354403
sub _nop {
355404
emit(0x90);
356405
}

t5-x64/01_sanity.t

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ say "1..4";
5959
my $here = label;
6060
_xchg( rax, rcx );
6161
_bind($here);
62+
_neg( rbx );
6263
_jmp($here);
6364
say "# xchg " . to_hex();
6465
say "# label pos=", $here->pos();

0 commit comments

Comments
 (0)