799039 | 2006-04-27 | Tor Edvardsson | |
#include "operators.h"
#include "constants.h"
#include "object.h"
#include "builtin_functions.h"
#ifdef REG_NONE
#undef REG_NONE
#endif
enum amd64_reg {REG_RAX = 0, REG_RBX = 3, REG_RCX = 1, REG_RDX = 2,
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | REG_RSP = 4, REG_RBP = 5, REG_RSI = 6, REG_RDI = 7,
REG_R8 = 8, REG_R9 = 9, REG_R10 = 10, REG_R11 = 11,
REG_R12 = 12, REG_R13 = 13, REG_R14 = 14, REG_R15 = 15,
REG_NONE = 4};
|
799039 | 2006-04-27 | Tor Edvardsson | |
|
302d10 | 2011-05-20 | Henrik Grubbström (Grubba) | |
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | #define REG_BITMASK ((1 << REG_MAX) - 1)
|
302d10 | 2011-05-20 | Henrik Grubbström (Grubba) | | #define REG_RESERVED (REG_RSP|REG_RBP|REG_RBX)
|
639a93 | 2011-05-15 | Henrik Grubbström (Grubba) | | #define REG_MAX REG_R12
#define PIKE_MARK_SP_REG REG_R12
#define PIKE_SP_REG REG_R13
#define PIKE_FP_REG REG_R14
#define Pike_interpreter_reg REG_R15
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | |
#ifdef __NT__
#define ARG1_REG REG_RCX
#define ARG2_REG REG_RDX
#define ARG3_REG REG_R8
#define ARG4_REG REG_R9
#else
#define ARG1_REG REG_RDI
#define ARG2_REG REG_RSI
#define ARG3_REG REG_RDX
#define ARG4_REG REG_RCX
#define ARG5_REG REG_R8
#define ARG6_REG REG_R9
#endif
|
799039 | 2006-04-27 | Tor Edvardsson | |
|
719c3a | 2012-06-12 | Per Hedbor | |
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | #define MAX_LABEL_USES 6
|
719c3a | 2012-06-12 | Per Hedbor | | struct label {
int n_label_uses;
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | ptrdiff_t addr;
|
719c3a | 2012-06-12 | Per Hedbor | | ptrdiff_t offset[MAX_LABEL_USES];
};
static void label( struct label *l )
{
int i;
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | if (l->addr >= 0) Pike_fatal("Label reused.\n");
|
719c3a | 2012-06-12 | Per Hedbor | | for( i=0; i<l->n_label_uses; i++ )
{
int dist = PIKE_PC - (l->offset[i] + 1);
if( dist > 0x7f || dist < -0x80 )
Pike_fatal("Branch too far\n");
Pike_compiler->new_program->program[l->offset[i]] = dist;
}
l->n_label_uses = 0;
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | l->addr = PIKE_PC;
|
719c3a | 2012-06-12 | Per Hedbor | | }
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void ib( char x )
{
add_to_program( x );
}
static void iw( short x )
{
add_to_program( x>>8 );
add_to_program( x );
}
static void id( int x )
{
add_to_program( (x)&0xff );
add_to_program( (x>>8)&0xff );
add_to_program( (x>>16)&0xff );
add_to_program( (x>>24)&0xff );
}
#define opcode(X) ib(X)
|
719c3a | 2012-06-12 | Per Hedbor | | static void modrm( int mod, int r, int m )
{
|
99c1e9 | 2012-06-20 | Per Hedbor | | ib( ((mod<<6) | ((r&0x7)<<3) | (m&0x7)) );
|
719c3a | 2012-06-12 | Per Hedbor | | }
static void sib( int scale, int index, enum amd64_reg base )
{
|
99c1e9 | 2012-06-20 | Per Hedbor | | ib( (scale<<6) | ((index&0x7)<<3) | (base&0x7) );
}
static void modrm_sib( int mod, int r, int m )
{
modrm( mod, r, m );
if( (m&7) == REG_RSP)
sib(0, REG_RSP, REG_RSP );
|
719c3a | 2012-06-12 | Per Hedbor | | }
static void rex( int w, enum amd64_reg r, int x, enum amd64_reg b )
{
unsigned char res = 1<<6;
if( w ) res |= 1<<3;
if( r > 0x7 ) res |= 1<<2;
if( x ) res |= 1<<1;
if( b > 0x7 ) res |= 1<<0;
if( res != (1<<6) )
add_to_program( res );
}
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void offset_modrm_sib( int offset, int r, int m )
|
719c3a | 2012-06-12 | Per Hedbor | | {
|
99c1e9 | 2012-06-20 | Per Hedbor | |
if( offset < -128 || offset > 127 )
{
modrm_sib( 2, r, m );
id( offset );
}
else if( offset || (m&7) == REG_RSP || (m&7) == REG_RBP )
{
modrm_sib( 1, r, m );
ib( offset );
}
else
{
modrm_sib( 0, r, m );
}
|
719c3a | 2012-06-12 | Per Hedbor | | }
static void ret()
{
opcode(0xc3);
}
static void push(enum amd64_reg reg )
{
if (reg & 0x08) add_to_program(0x41);
add_to_program(0x50 + (reg & 0x07));
}
static void pop(enum amd64_reg reg )
{
if (reg & 0x08) add_to_program(0x41);
add_to_program(0x58 + (reg & 0x07));
}
static void mov_reg_reg(enum amd64_reg from_reg, enum amd64_reg to_reg )
{
rex( 1, from_reg, 0, to_reg );
opcode( 0x89 );
modrm( 3, from_reg, to_reg );
}
|
799039 | 2006-04-27 | Tor Edvardsson | | #define PUSH_INT(X) ins_int((INT32)(X), (void (*)(char))add_to_program)
|
6785ae | 2012-06-15 | Per Hedbor | | static void low_mov_mem_reg(enum amd64_reg from_reg, ptrdiff_t offset,
enum amd64_reg to_reg)
|
719c3a | 2012-06-12 | Per Hedbor | | {
opcode( 0x8b );
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib(offset, to_reg, from_reg );
|
719c3a | 2012-06-12 | Per Hedbor | | }
static void mov_mem_reg( enum amd64_reg from_reg, ptrdiff_t offset, enum amd64_reg to_reg )
{
rex( 1, to_reg, 0, from_reg );
low_mov_mem_reg( from_reg, offset, to_reg );
}
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void xor_reg_reg( enum amd64_reg reg1, enum amd64_reg reg2 )
|
719c3a | 2012-06-12 | Per Hedbor | | {
|
99c1e9 | 2012-06-20 | Per Hedbor | | rex(1,reg1,0,reg2);
opcode( 0x31 );
modrm(3,reg1,reg2);
|
719c3a | 2012-06-12 | Per Hedbor | | }
static void and_reg_imm( enum amd64_reg reg, int imm32 )
{
rex( 1, 0, 0, reg );
if( imm32 < -0x80 || imm32 > 0x7f )
{
if( reg == REG_RAX )
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x25 );
|
719c3a | 2012-06-12 | Per Hedbor | | id( imm32 );
}
else
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x81 );
|
719c3a | 2012-06-12 | Per Hedbor | | modrm( 3,4, reg);
id( imm32 );
}
}
else
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | add_to_program(0x83);
|
719c3a | 2012-06-12 | Per Hedbor | | modrm( 3, 4, reg );
ib( imm32 );
}
}
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void mov_mem32_reg( enum amd64_reg from_reg, ptrdiff_t offset, enum amd64_reg to_reg )
{
rex( 0, to_reg, 0, from_reg );
low_mov_mem_reg( from_reg, offset, to_reg );
}
|
719c3a | 2012-06-12 | Per Hedbor | | static void mov_mem16_reg( enum amd64_reg from_reg, ptrdiff_t offset, enum amd64_reg to_reg )
{
|
99c1e9 | 2012-06-20 | Per Hedbor | |
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem32_reg( from_reg, offset, to_reg );
|
99c1e9 | 2012-06-20 | Per Hedbor | | and_reg_imm(to_reg, 0xffff);
|
719c3a | 2012-06-12 | Per Hedbor | | }
static void add_reg_imm( enum amd64_reg src, int imm32);
static void shl_reg_imm( enum amd64_reg from_reg, int shift )
{
rex( 1, from_reg, 0, 0 );
if( shift == 1 )
{
|
b233f4 | 2012-06-17 | Henrik Grubbström (Grubba) | | opcode( 0xd1 );
modrm( 3, 4, from_reg );
|
719c3a | 2012-06-12 | Per Hedbor | | }
else
{
opcode( 0xc1 );
|
b233f4 | 2012-06-17 | Henrik Grubbström (Grubba) | | modrm( 3, 4, from_reg );
|
719c3a | 2012-06-12 | Per Hedbor | | ib( shift );
}
}
static void clear_reg( enum amd64_reg reg )
{
xor_reg_reg( reg, reg );
}
|
6785ae | 2012-06-15 | Per Hedbor | | static void neg_reg( enum amd64_reg reg )
{
rex(1,0,0,reg);
opcode(0xf7);
modrm(3,3,reg);
}
|
719c3a | 2012-06-12 | Per Hedbor | | static void mov_imm_reg( long imm, enum amd64_reg reg )
{
if( (imm > 0x7fffffffLL) || (imm < -0x80000000LL) )
{
rex(1,0,0,reg);
opcode(0xb8 | (reg&0x7));
id( (imm & 0xffffffffLL) );
id( ((imm >> 32)&0xffffffffLL) );
}
else
{
rex(1,0,0,reg);
opcode( 0xc7 );
modrm( 3,0,reg );
id( (int)imm );
}
}
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void low_mov_reg_mem(enum amd64_reg from_reg, enum amd64_reg to_reg, ptrdiff_t offset )
{
opcode( 0x89 );
offset_modrm_sib( offset, from_reg, to_reg );
}
|
719c3a | 2012-06-12 | Per Hedbor | | static void mov_reg_mem( enum amd64_reg from_reg, enum amd64_reg to_reg, ptrdiff_t offset )
{
rex(1, from_reg, 0, to_reg );
|
99c1e9 | 2012-06-20 | Per Hedbor | | low_mov_reg_mem( from_reg, to_reg, offset );
}
|
719c3a | 2012-06-12 | Per Hedbor | |
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void mov_reg_mem32( enum amd64_reg from_reg, enum amd64_reg to_reg, ptrdiff_t offset )
{
rex(0, from_reg, 0, to_reg );
low_mov_reg_mem( from_reg, to_reg, offset );
}
static void mov_reg_mem16( enum amd64_reg from_reg, enum amd64_reg to_reg, ptrdiff_t offset )
{
opcode( 0x66 );
rex(0, from_reg, 0, to_reg );
low_mov_reg_mem( from_reg, to_reg, offset );
|
719c3a | 2012-06-12 | Per Hedbor | | }
|
99c1e9 | 2012-06-20 | Per Hedbor | |
|
719c3a | 2012-06-12 | Per Hedbor | | static void mov_imm_mem( long imm, enum amd64_reg to_reg, ptrdiff_t offset )
{
if( imm >= -0x80000000LL && imm <= 0x7fffffffLL )
{
rex( 1, 0, 0, to_reg );
opcode( 0xc7 );
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib( offset, 0, to_reg );
|
719c3a | 2012-06-12 | Per Hedbor | | id( imm );
}
else
{
if( to_reg == REG_RAX )
Pike_fatal( "Clobbered TMP REG_RAX reg\n");
mov_imm_reg( imm, REG_RAX );
mov_reg_mem( REG_RAX, to_reg, offset );
}
}
static void mov_imm_mem32( int imm, enum amd64_reg to_reg, ptrdiff_t offset )
{
rex( 0, 0, 0, to_reg );
opcode( 0xc7 );
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib( offset, 0, to_reg );
|
719c3a | 2012-06-12 | Per Hedbor | | id( imm );
}
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void sub_reg_imm( enum amd64_reg reg, int imm32 );
|
719c3a | 2012-06-12 | Per Hedbor | | static void add_reg_imm( enum amd64_reg reg, int imm32 )
{
if( !imm32 ) return;
|
99c1e9 | 2012-06-20 | Per Hedbor | | if( imm32 < 0 )
{
sub_reg_imm( reg, -imm32 );
return;
}
|
719c3a | 2012-06-12 | Per Hedbor | |
rex( 1, 0, 0, reg );
if( imm32 < -0x80 || imm32 > 0x7f )
{
if( reg == REG_RAX )
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x05 );
|
719c3a | 2012-06-12 | Per Hedbor | | id( imm32 );
}
else
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x81 );
|
719c3a | 2012-06-12 | Per Hedbor | | modrm( 3, 0, reg);
id( imm32 );
}
}
else
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | add_to_program(0x83);
|
719c3a | 2012-06-12 | Per Hedbor | | modrm( 3, 0, reg );
ib( imm32 );
}
}
|
99c1e9 | 2012-06-20 | Per Hedbor | |
static void low_add_mem_imm(int w, enum amd64_reg reg, int offset, int imm32 )
|
719c3a | 2012-06-12 | Per Hedbor | | {
int r2 = imm32 == -1 ? 1 : 0;
int large = 0;
if( !imm32 ) return;
|
99c1e9 | 2012-06-20 | Per Hedbor | | rex( w, 0, 0, reg );
|
719c3a | 2012-06-12 | Per Hedbor | |
if( r2 ) imm32 = -imm32;
if( imm32 == 1 )
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0xff );
|
719c3a | 2012-06-12 | Per Hedbor | | else if( imm32 >= -128 && imm32 < 128 )
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x83 );
|
719c3a | 2012-06-12 | Per Hedbor | | else
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x81 );
|
719c3a | 2012-06-12 | Per Hedbor | | large = 1;
}
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib( offset, r2, reg );
|
719c3a | 2012-06-12 | Per Hedbor | | if( imm32 != 1 )
{
if( large )
id( imm32 );
else
ib( imm32 );
}
}
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void add_mem32_imm( enum amd64_reg reg, int offset, int imm32 )
|
719c3a | 2012-06-12 | Per Hedbor | | {
|
99c1e9 | 2012-06-20 | Per Hedbor | | low_add_mem_imm( 0, reg, offset, imm32 );
|
6785ae | 2012-06-15 | Per Hedbor | | }
|
99c1e9 | 2012-06-20 | Per Hedbor | | static void add_mem_imm( enum amd64_reg reg, int offset, int imm32 )
|
6785ae | 2012-06-15 | Per Hedbor | | {
|
99c1e9 | 2012-06-20 | Per Hedbor | | low_add_mem_imm( 1, reg, offset, imm32 );
|
6785ae | 2012-06-15 | Per Hedbor | | }
static void add_mem8_imm( enum amd64_reg reg, int offset, int imm32 )
{
int r2 = imm32 == -1 ? 1 : 0;
if( !imm32 ) return;
rex( 0, 0, 0, reg );
if( imm32 == 1 || imm32 == -1 )
opcode( 0xfe );
else if( imm32 >= -128 && imm32 < 128 )
opcode( 0x80 );
else
Pike_fatal("Not sensible");
|
719c3a | 2012-06-12 | Per Hedbor | |
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib( offset, r2, reg );
|
6785ae | 2012-06-15 | Per Hedbor | | if( imm32 != 1 && !r2 )
{
|
719c3a | 2012-06-12 | Per Hedbor | | ib( imm32 );
|
6785ae | 2012-06-15 | Per Hedbor | | }
|
719c3a | 2012-06-12 | Per Hedbor | | }
static void sub_reg_imm( enum amd64_reg reg, int imm32 )
{
if( !imm32 ) return;
|
99c1e9 | 2012-06-20 | Per Hedbor | | if( imm32 < 0 )
return add_reg_imm( reg, -imm32 );
|
719c3a | 2012-06-12 | Per Hedbor | | rex( 1, 0, 0, reg );
if( imm32 < -0x80 || imm32 > 0x7f )
{
if( reg == REG_RAX )
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x2d );
|
719c3a | 2012-06-12 | Per Hedbor | | id( imm32 );
}
else
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x81 );
|
719c3a | 2012-06-12 | Per Hedbor | | modrm( 3, 5, reg);
id( imm32 );
}
}
else
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode(0x83);
|
719c3a | 2012-06-12 | Per Hedbor | | modrm( 3, 5, reg );
ib( imm32 );
}
}
static void test_reg_reg( enum amd64_reg reg1, enum amd64_reg reg2 )
{
rex(1,reg1,0,reg2);
opcode(0x85);
modrm(3, reg1, reg2 );
}
static void test_reg( enum amd64_reg reg1 )
{
test_reg_reg( reg1, reg1 );
}
static void cmp_reg_imm( enum amd64_reg reg, int imm32 )
{
rex(1, 0, 0, reg);
if( imm32 > 0x7f || imm32 < -0x80 )
{
if( reg == REG_RAX )
{
opcode( 0x3d );
id( imm32 );
}
else
{
opcode( 0x81 );
modrm(3,7,reg);
id( imm32 );
}
}
else
{
opcode( 0x83 );
modrm( 3,7,reg);
ib( imm32 );
}
}
static void cmp_reg_reg( enum amd64_reg reg1, enum amd64_reg reg2 )
{
rex(1, reg1, 0, reg2);
opcode( 0x39 );
modrm( 3, reg1, reg2 );
}
static int jmp_rel_imm32( int rel )
{
int res;
opcode( 0xe9 );
res = PIKE_PC;
id( rel );
return res;
}
static void jmp_rel_imm( int rel )
{
if(rel >= -0x80 && rel <= 0x7f )
{
opcode( 0xeb );
ib( rel );
return;
}
jmp_rel_imm32( rel );
}
|
6785ae | 2012-06-15 | Per Hedbor | | static void call_rel_imm32( int rel )
{
rel -= 5;
opcode( 0xe8 );
id( rel );
return;
}
|
719c3a | 2012-06-12 | Per Hedbor | | static void jmp_reg( enum amd64_reg reg )
{
rex(0,reg,0,0);
opcode( 0xff );
modrm( 3, 4, reg );
}
static void call_reg( enum amd64_reg reg )
{
rex(0,reg,0,0);
opcode( 0xff );
modrm( 3, 2, reg );
}
static void call_imm( void *ptr )
{
size_t addr = (size_t)ptr;
if( (addr & ~0x7fffffffLL) && !(addr & ~0x3fffffff8LL) )
{
mov_imm_reg( addr>>3, REG_RAX);
shl_reg_imm( REG_RAX, 3 );
}
else
{
mov_imm_reg(addr, REG_RAX );
}
call_reg( REG_RAX );
}
|
6785ae | 2012-06-15 | Per Hedbor | |
static void add_reg_reg( enum amd64_reg reg, enum amd64_reg reg2 )
{
rex(1,reg2,0,reg);
opcode( 0x1 );
modrm( 3, reg2, reg );
}
static void sub_reg_reg( enum amd64_reg reg, enum amd64_reg reg2 )
{
rex(1,reg2,0,reg);
opcode( 0x29 );
modrm( 3, reg2, reg );
}
static void add_reg_mem( enum amd64_reg dst, enum amd64_reg src, long off )
{
rex(1,dst,0,src);
opcode( 0x3 );
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib( off, dst, src );
|
6785ae | 2012-06-15 | Per Hedbor | | }
static void sub_reg_mem( enum amd64_reg dst, enum amd64_reg src, long off )
{
rex(1,dst,0,src);
opcode( 0x2b );
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib( off, dst, src );
|
6785ae | 2012-06-15 | Per Hedbor | | }
|
719c3a | 2012-06-12 | Per Hedbor | |
static void add_reg_imm_reg( enum amd64_reg src, long imm32, enum amd64_reg dst )
{
if( imm32 > 0x7fffffffLL ||
imm32 <-0x80000000LL)
Pike_fatal("LEA [reg+imm] > 32bit Not supported\n");
if( src == dst )
{
if( !imm32 ) return;
add_reg_imm( src, imm32 );
}
else
{
if( !imm32 )
{
mov_reg_reg( src, dst );
return;
}
rex(1,dst,0,src);
opcode( 0x8d );
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib( imm32, dst, src );
|
719c3a | 2012-06-12 | Per Hedbor | | }
}
static void mov_rip_imm_reg( int imm, enum amd64_reg reg )
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | imm -= 7;
|
719c3a | 2012-06-12 | Per Hedbor | |
rex( 1, reg, 0, 0 );
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x8d );
|
719c3a | 2012-06-12 | Per Hedbor | | modrm( 0, reg, 5 );
id( imm );
}
static void add_imm_mem( int imm32, enum amd64_reg reg, int offset )
{
int r2 = (imm32 == -1) ? 1 : 0;
int large = 0;
rex( 1, 0, 0, reg );
if( imm32 == 1 || imm32 == -1 )
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0xff );
|
719c3a | 2012-06-12 | Per Hedbor | | else if( -128 <= imm32 && 128 > imm32 )
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x83 );
|
719c3a | 2012-06-12 | Per Hedbor | | else
{
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | opcode( 0x81 );
|
719c3a | 2012-06-12 | Per Hedbor | | large = 1;
}
|
99c1e9 | 2012-06-20 | Per Hedbor | | offset_modrm_sib( offset, r2, reg );
|
719c3a | 2012-06-12 | Per Hedbor | |
if( imm32 != 1 && !r2 )
{
if( large )
id( imm32 );
else
ib( imm32 );
}
}
static void jump_rel8( struct label *res, unsigned char op )
{
opcode( op );
|
799039 | 2006-04-27 | Tor Edvardsson | |
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | if (res->addr >= 0) {
ib(res->addr - (PIKE_PC+1));
return;
}
|
719c3a | 2012-06-12 | Per Hedbor | | if( res->n_label_uses >= MAX_LABEL_USES )
Pike_fatal( "Label used too many times\n" );
res->offset[res->n_label_uses] = PIKE_PC;
res->n_label_uses++;
ib(0);
}
static int jnz_imm_rel32( int rel )
{
int res;
opcode( 0xf );
opcode( 0x85 );
res = PIKE_PC;
id( rel );
return res;
}
static int jz_imm_rel32( int rel )
{
int res;
opcode( 0xf );
opcode( 0x84 );
res = PIKE_PC;
id( rel );
return res;
}
#define jne(X) jnz(X)
#define je(X) jz(X)
static void jmp( struct label *l ) { return jump_rel8( l, 0xeb ); }
static void jg( struct label *l ) { return jump_rel8( l, 0x7f ); }
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | static void jge( struct label *l ) { return jump_rel8( l, 0x7d ); }
|
b505a7 | 2012-06-13 | Per Hedbor | | static void jl( struct label *l ) { return jump_rel8( l, 0x7c ); }
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | static void jle( struct label *l ) { return jump_rel8( l, 0x7e ); }
|
719c3a | 2012-06-12 | Per Hedbor | | static void jo( struct label *l ) { return jump_rel8( l, 0x70 ); }
|
6785ae | 2012-06-15 | Per Hedbor | | static void jno( struct label *l ) { return jump_rel8( l, 0x71 ); }
|
91080b | 2012-06-15 | Henrik Grubbström (Grubba) | | static void jc( struct label *l ) { return jump_rel8( l, 0x72 ); }
static void jnc( struct label *l ) { return jump_rel8( l, 0x73 ); }
|
6785ae | 2012-06-15 | Per Hedbor | | static void jz( struct label *l ) { return jump_rel8( l, 0x74 ); }
static void jnz( struct label *l ) { return jump_rel8( l, 0x75 ); }
|
719c3a | 2012-06-12 | Per Hedbor | |
|
6785ae | 2012-06-15 | Per Hedbor | | #define LABELS() struct label label_A, label_B, label_C, label_D;label_A.addr = -1;label_A.n_label_uses = 0;label_B.addr = -1;label_B.n_label_uses = 0;label_C.addr = -1;label_C.n_label_uses = 0;label_D.addr = -1;label_D.n_label_uses = 0;
|
719c3a | 2012-06-12 | Per Hedbor | | #define LABEL_A label(&label_A)
#define LABEL_B label(&label_B)
#define LABEL_C label(&label_C)
|
6785ae | 2012-06-15 | Per Hedbor | | #define LABEL_D label(&label_D)
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | |
|
639a93 | 2011-05-15 | Henrik Grubbström (Grubba) | | * R15: Pike_interpreter
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | */
void amd64_ins_entry(void)
{
|
719c3a | 2012-06-12 | Per Hedbor | | push(REG_RBP);
mov_reg_reg(REG_RSP, REG_RBP);
push(REG_R15);
push(REG_R14);
push(REG_R13);
push(REG_R12);
push(REG_RBX);
sub_reg_imm(REG_RSP, 8);
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | |
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_reg(ARG1_REG, Pike_interpreter_reg);
|
639a93 | 2011-05-15 | Henrik Grubbström (Grubba) | |
amd64_flush_code_generator_state();
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | }
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | static enum amd64_reg sp_reg = 0, fp_reg = 0, mark_sp_reg = 0;
|
719c3a | 2012-06-12 | Per Hedbor | | static int dirty_regs = 0, ret_for_func = 0;
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | ptrdiff_t amd64_prev_stored_pc = -1;
|
6785ae | 2012-06-15 | Per Hedbor | | static int branch_check_threads_update_etc = -1;
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | |
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | void amd64_flush_code_generator_state(void)
{
sp_reg = 0;
fp_reg = 0;
mark_sp_reg = 0;
dirty_regs = 0;
|
719c3a | 2012-06-12 | Per Hedbor | | ret_for_func = 0;
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | amd64_prev_stored_pc = -1;
|
6785ae | 2012-06-15 | Per Hedbor | | branch_check_threads_update_etc = -1;
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | }
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | static void flush_dirty_regs(void)
{
if (dirty_regs & (1 << PIKE_SP_REG)) {
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_mem(PIKE_SP_REG, Pike_interpreter_reg,
|
d97eb7 | 2011-07-10 | Henrik Grubbström (Grubba) | | OFFSETOF(Pike_interpreter_struct, stack_pointer));
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | dirty_regs &= ~(1 << PIKE_SP_REG);
}
if (dirty_regs & (1 << PIKE_MARK_SP_REG)) {
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_mem(PIKE_MARK_SP_REG, Pike_interpreter_reg,
|
d97eb7 | 2011-07-10 | Henrik Grubbström (Grubba) | | OFFSETOF(Pike_interpreter_struct, mark_stack_pointer));
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | dirty_regs &= ~(1 << PIKE_MARK_SP_REG);
}
}
|
799039 | 2006-04-27 | Tor Edvardsson | |
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | |
void amd64_load_fp_reg(void)
{
if (!fp_reg) {
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(Pike_interpreter_reg,
|
6785ae | 2012-06-15 | Per Hedbor | | OFFSETOF(Pike_interpreter_struct, frame_pointer),
PIKE_FP_REG);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | fp_reg = PIKE_FP_REG;
}
}
void amd64_load_sp_reg(void)
{
if (!sp_reg) {
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(Pike_interpreter_reg,
|
6785ae | 2012-06-15 | Per Hedbor | | OFFSETOF(Pike_interpreter_struct, stack_pointer),
PIKE_SP_REG);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | sp_reg = PIKE_SP_REG;
}
}
void amd64_load_mark_sp_reg(void)
{
if (!mark_sp_reg) {
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(Pike_interpreter_reg,
|
6785ae | 2012-06-15 | Per Hedbor | | OFFSETOF(Pike_interpreter_struct, mark_stack_pointer),
PIKE_MARK_SP_REG);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | mark_sp_reg = PIKE_MARK_SP_REG;
}
}
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | static void update_arg1(INT32 value)
{
|
719c3a | 2012-06-12 | Per Hedbor | | mov_imm_reg(value, ARG1_REG);
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | |
}
|
799039 | 2006-04-27 | Tor Edvardsson | |
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | static void update_arg2(INT32 value)
{
|
719c3a | 2012-06-12 | Per Hedbor | | mov_imm_reg(value, ARG2_REG);
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | |
|
799039 | 2006-04-27 | Tor Edvardsson | | }
|
719c3a | 2012-06-12 | Per Hedbor | | static void amd64_add_sp( int num )
{
amd64_load_sp_reg();
|
6785ae | 2012-06-15 | Per Hedbor | | add_reg_imm( sp_reg, sizeof(struct svalue)*num);
|
719c3a | 2012-06-12 | Per Hedbor | | dirty_regs |= 1 << PIKE_SP_REG;
flush_dirty_regs();
}
static void amd64_add_mark_sp( int num )
{
amd64_load_mark_sp_reg();
add_reg_imm( mark_sp_reg, sizeof(struct svalue*)*num);
dirty_regs |= 1 << PIKE_MARK_SP_REG;
}
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | |
static void amd64_push_svaluep(int reg)
{
|
719c3a | 2012-06-12 | Per Hedbor | | LABELS();
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | amd64_load_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(reg, OFFSETOF(svalue, type), REG_RAX);
mov_mem_reg(reg, OFFSETOF(svalue, u.refs), REG_RCX);
mov_reg_mem(REG_RAX, sp_reg, OFFSETOF(svalue, type));
and_reg_imm(REG_RAX, 0x1f);
mov_reg_mem(REG_RCX, sp_reg, OFFSETOF(svalue, u.refs));
cmp_reg_imm(REG_RAX, MAX_REF_TYPE);
jg(&label_A);
add_imm_mem( 1, REG_RCX,OFFSETOF(pike_string, refs));
LABEL_A;
amd64_add_sp( 1 );
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | }
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | static void amd64_push_int(INT64 value, int subtype)
{
amd64_load_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_imm_mem((subtype<<16) + PIKE_T_INT, sp_reg, OFFSETOF(svalue, type));
mov_imm_mem(value, sp_reg, OFFSETOF(svalue, u.integer));
amd64_add_sp( 1 );
}
static void amd64_push_int_reg(enum amd64_reg reg )
{
if( reg == REG_RCX ) Pike_fatal( "Source clobbered in push_int_reg\n");
amd64_load_sp_reg();
mov_imm_mem( PIKE_T_INT, sp_reg, OFFSETOF(svalue, type));
mov_reg_mem( reg, sp_reg, OFFSETOF(svalue, u.integer));
amd64_add_sp( 1 );
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | }
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | |
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | static void amd64_mark(int offset)
{
amd64_load_sp_reg();
amd64_load_mark_sp_reg();
if (offset) {
|
719c3a | 2012-06-12 | Per Hedbor | | add_reg_imm_reg(sp_reg, -offset * sizeof(struct svalue), REG_RAX);
mov_reg_mem(REG_RAX, mark_sp_reg, 0);
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | } else {
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_mem(sp_reg, mark_sp_reg, 0);
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | }
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_add_mark_sp( 1 );
}
static void mov_sval_type(enum amd64_reg src, enum amd64_reg dst )
{
mov_mem32_reg( src, OFFSETOF(svalue,type), dst);
and_reg_imm( dst, 0x1f );
}
static void amd64_call_c_function(void *addr)
{
flush_dirty_regs();
call_imm(addr);
}
static void amd64_free_svalue(enum amd64_reg src, int guaranteed_ref )
{
LABELS();
if( src == REG_RAX )
Pike_fatal("Clobbering RAX for free-svalue\n");
mov_sval_type( src, REG_RAX );
cmp_reg_imm( REG_RAX,MAX_REF_TYPE);
jg( &label_A );
mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX);
add_mem32_imm( REG_RAX, OFFSETOF(pike_string,refs), -1);
if( !guaranteed_ref )
{
jnz( &label_A );
|
99c1e9 | 2012-06-20 | Per Hedbor | |
if( src != ARG1_REG )
mov_reg_reg( src, ARG1_REG );
amd64_call_c_function(really_free_svalue);
}
LABEL_A;
}
static void amd64_free_svalue_type(enum amd64_reg src, enum amd64_reg type,
int guaranteed_ref )
{
LABELS();
if( src == REG_RAX )
Pike_fatal("Clobbering RAX for free-svalue\n");
cmp_reg_imm(type,MAX_REF_TYPE);
jg( &label_A );
mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX);
add_mem32_imm( REG_RAX, OFFSETOF(pike_string,refs), -1);
if( !guaranteed_ref )
{
jnz( &label_A );
|
719c3a | 2012-06-12 | Per Hedbor | | if( src != ARG1_REG )
mov_reg_reg( src, ARG1_REG );
amd64_call_c_function(really_free_svalue);
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | }
|
719c3a | 2012-06-12 | Per Hedbor | | LABEL_A;
}
|
b505a7 | 2012-06-13 | Per Hedbor | | void amd64_ref_svalue( enum amd64_reg src, int already_have_type )
|
719c3a | 2012-06-12 | Per Hedbor | | {
LABELS();
if( src == REG_RAX ) Pike_fatal("Clobbering src in ref_svalue\n");
|
b505a7 | 2012-06-13 | Per Hedbor | | if( !already_have_type )
mov_sval_type( src, REG_RAX );
else
and_reg_imm( REG_RAX, 0x1f );
|
719c3a | 2012-06-12 | Per Hedbor | |
cmp_reg_imm(REG_RAX, MAX_REF_TYPE );
jg( &label_A );
mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX);
add_mem32_imm( REG_RAX, OFFSETOF(pike_string,refs), 1);
LABEL_A;
}
void amd64_assign_local( int b )
{
amd64_load_fp_reg();
amd64_load_sp_reg();
mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);
add_reg_imm( ARG1_REG,b*sizeof(struct svalue) );
mov_reg_reg( ARG1_REG, REG_RBX );
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | |
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_free_svalue(ARG1_REG, 0);
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | |
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(sp_reg, -1*sizeof(struct svalue), REG_RAX);
mov_mem_reg(sp_reg, -1*sizeof(struct svalue)+sizeof(long), REG_RCX);
mov_reg_mem( REG_RAX, REG_RBX, 0 );
mov_reg_mem( REG_RCX, REG_RBX, sizeof(long) );
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | }
static void amd64_pop_mark(void)
{
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_add_mark_sp( -1 );
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | }
static void amd64_push_string(int strno, int subtype)
{
amd64_load_fp_reg();
amd64_load_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(fp_reg, OFFSETOF(pike_frame, context), REG_RAX);
mov_mem_reg(REG_RAX, OFFSETOF(inherit, prog), REG_RAX);
mov_mem_reg(REG_RAX, OFFSETOF(program, strings), REG_RAX);
mov_mem_reg(REG_RAX, strno * sizeof(struct pike_string *), REG_RAX);
mov_imm_mem((subtype<<16) | PIKE_T_STRING, sp_reg, OFFSETOF(svalue, type));
mov_reg_mem(REG_RAX, sp_reg,(INT32)OFFSETOF(svalue, u.string));
add_imm_mem( 1, REG_RAX, OFFSETOF(pike_string, refs));
amd64_add_sp(1);
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | }
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | static void amd64_push_local_function(int fun)
{
amd64_load_fp_reg();
amd64_load_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(fp_reg, OFFSETOF(pike_frame, context), REG_RAX);
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, current_object),
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | REG_RCX);
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem32_reg(REG_RAX, OFFSETOF(inherit, identifier_level),
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | REG_RAX);
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_mem(REG_RCX, sp_reg, OFFSETOF(svalue, u.object));
add_reg_imm(REG_RAX, fun);
add_imm_mem( 1, REG_RCX,(INT32)OFFSETOF(object, refs));
shl_reg_imm(REG_RAX, 16);
add_reg_imm(REG_RAX, PIKE_T_FUNCTION);
mov_reg_mem(REG_RAX, sp_reg, OFFSETOF(svalue, type));
amd64_add_sp(1);
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | }
|
fa07a9 | 2011-05-16 | Henrik Grubbström (Grubba) | | static void amd64_stack_error(void)
{
Pike_fatal("Stack error\n");
}
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | void amd64_update_pc(void)
{
INT32 tmp = PIKE_PC, disp;
|
719c3a | 2012-06-12 | Per Hedbor | |
if(amd64_prev_stored_pc == - 1)
{
enum amd64_reg tmp_reg = REG_RAX;
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | amd64_load_fp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_rip_imm_reg(tmp - PIKE_PC, tmp_reg);
mov_reg_mem(tmp_reg, fp_reg, OFFSETOF(pike_frame, pc));
|
799039 | 2006-04-27 | Tor Edvardsson | | #ifdef PIKE_DEBUG
if (a_flag >= 60)
|
719c3a | 2012-06-12 | Per Hedbor | | fprintf (stderr, "pc %d update pc via lea\n", tmp);
|
799039 | 2006-04-27 | Tor Edvardsson | | #endif
|
bf49e1 | 2012-06-15 | Henrik Grubbström (Grubba) | | amd64_prev_stored_pc = tmp;
|
799039 | 2006-04-27 | Tor Edvardsson | | }
|
719c3a | 2012-06-12 | Per Hedbor | | else if ((disp = tmp - amd64_prev_stored_pc))
{
|
799039 | 2006-04-27 | Tor Edvardsson | | #ifdef PIKE_DEBUG
if (a_flag >= 60)
fprintf (stderr, "pc %d update pc relative: %d\n", tmp, disp);
#endif
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | amd64_load_fp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | add_imm_mem(disp, fp_reg, OFFSETOF (pike_frame, pc));
|
bf49e1 | 2012-06-15 | Henrik Grubbström (Grubba) | | amd64_prev_stored_pc += disp;
|
799039 | 2006-04-27 | Tor Edvardsson | | }
|
719c3a | 2012-06-12 | Per Hedbor | | else {
|
799039 | 2006-04-27 | Tor Edvardsson | | #ifdef PIKE_DEBUG
if (a_flag >= 60)
fprintf (stderr, "pc %d update pc - already up-to-date\n", tmp);
#endif
|
719c3a | 2012-06-12 | Per Hedbor | | }
#if 0
|
fa07a9 | 2011-05-16 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if (d_flag) {
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_reg(REG_RSP, REG_RAX);
and_reg_imm(REG_RAX, 0x08);
|
fa07a9 | 2011-05-16 | Henrik Grubbström (Grubba) | | AMD64_JE(0x09);
|
719c3a | 2012-06-12 | Per Hedbor | | call_imm(amd64_stack_error);
|
fa07a9 | 2011-05-16 | Henrik Grubbström (Grubba) | | }
#endif
|
719c3a | 2012-06-12 | Per Hedbor | | #endif
|
799039 | 2006-04-27 | Tor Edvardsson | | }
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | static void maybe_update_pc(void)
{
static int last_prog_id=-1;
static size_t last_num_linenumbers=-1;
|
719c3a | 2012-06-12 | Per Hedbor | |
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | if(
|
799039 | 2006-04-27 | Tor Edvardsson | | #ifdef PIKE_DEBUG
d_flag ||
#endif
(amd64_prev_stored_pc == -1) ||
last_prog_id != Pike_compiler->new_program->id ||
last_num_linenumbers != Pike_compiler->new_program->num_linenumbers
) {
last_prog_id=Pike_compiler->new_program->id;
last_num_linenumbers = Pike_compiler->new_program->num_linenumbers;
UPDATE_PC();
}
}
|
719c3a | 2012-06-12 | Per Hedbor | | static void sync_registers(int flags)
{
maybe_update_pc();
flush_dirty_regs();
if (flags & I_UPDATE_SP) sp_reg = 0;
if (flags & I_UPDATE_M_SP) mark_sp_reg = 0;
if (flags & I_UPDATE_FP) fp_reg = 0;
}
static void amd64_call_c_opcode(void *addr, int flags)
{
sync_registers(flags);
call_imm( addr );
}
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
static void ins_debug_instr_prologue (PIKE_INSTR_T instr, INT32 arg1, INT32 arg2)
{
int flags = instrs[instr].flags;
maybe_update_pc();
if (flags & I_HASARG2)
|
719c3a | 2012-06-12 | Per Hedbor | | mov_imm_reg(arg2, ARG3_REG);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | if (flags & I_HASARG)
|
719c3a | 2012-06-12 | Per Hedbor | | mov_imm_reg(arg1, ARG2_REG);
mov_imm_reg(instr, ARG1_REG);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | |
if (flags & I_HASARG2)
amd64_call_c_function (simple_debug_instr_prologue_2);
else if (flags & I_HASARG)
amd64_call_c_function (simple_debug_instr_prologue_1);
else
amd64_call_c_function (simple_debug_instr_prologue_0);
}
#else /* !PIKE_DEBUG */
#define ins_debug_instr_prologue(instr, arg1, arg2)
#endif
|
719c3a | 2012-06-12 | Per Hedbor | | static void amd64_push_this_object( )
{
amd64_load_fp_reg();
amd64_load_sp_reg();
mov_imm_mem( PIKE_T_OBJECT, sp_reg, OFFSETOF(svalue,type));
mov_mem_reg( fp_reg, OFFSETOF(pike_frame, current_object), REG_RAX );
mov_reg_mem( REG_RAX, sp_reg, OFFSETOF(svalue,u.object) );
add_mem32_imm( REG_RAX, (INT32)OFFSETOF(object, refs), 1);
amd64_add_sp( 1 );
}
void amd64_ins_branch_check_threads_etc()
{
LABELS();
|
6785ae | 2012-06-15 | Per Hedbor | | #if 1
if( branch_check_threads_update_etc == -1 )
{
jmp( &label_A );
mov_imm_mem32( 0, REG_RSP, 0);
branch_check_threads_update_etc = PIKE_PC;
|
5e064b | 2012-06-15 | Henrik Grubbström (Grubba) | | if( (unsigned long long)&fast_check_threads_counter < 0x7fffffffULL )
|
6785ae | 2012-06-15 | Per Hedbor | | {
clear_reg( REG_RAX );
add_mem32_imm( REG_RAX,
|
5e064b | 2012-06-15 | Henrik Grubbström (Grubba) | | (int)(ptrdiff_t)&fast_check_threads_counter,
|
6785ae | 2012-06-15 | Per Hedbor | | 0x80 );
}
else
{
mov_imm_reg( (long)&fast_check_threads_counter, REG_RAX);
add_mem_imm( REG_RAX, 0, 0x80 );
}
|
5e064b | 2012-06-15 | Henrik Grubbström (Grubba) | | mov_imm_reg( (ptrdiff_t)branch_check_threads_etc, REG_RAX );
|
6785ae | 2012-06-15 | Per Hedbor | | jmp_reg(REG_RAX);
}
LABEL_A;
add_mem8_imm( REG_RSP, 0, 1 );
jno( &label_B );
call_rel_imm32( branch_check_threads_update_etc-PIKE_PC );
LABEL_B;
#else
call_imm( &branch_check_threads_etc );
#endif
|
719c3a | 2012-06-12 | Per Hedbor | | }
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | void amd64_init_interpreter_state(void)
{
instrs[F_CATCH - F_OFFSET].address = inter_return_opcode_F_CATCH;
}
|
6785ae | 2012-06-15 | Per Hedbor | | static void amd64_return_from_function()
{
if( ret_for_func )
{
jmp_rel_imm( ret_for_func - PIKE_PC );
}
else
{
ret_for_func = PIKE_PC;
pop(REG_RBX);
pop(REG_RBX);
pop(REG_R12);
pop(REG_R13);
pop(REG_R14);
pop(REG_R15);
pop(REG_RBP);
ret();
}
}
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | void ins_f_byte(unsigned int b)
{
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | int flags;
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | void *addr;
|
48f597 | 2011-05-23 | Henrik Grubbström (Grubba) | | INT32 rel_addr = 0;
|
719c3a | 2012-06-12 | Per Hedbor | | LABELS();
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | b-=F_OFFSET;
|
799039 | 2006-04-27 | Tor Edvardsson | | #ifdef PIKE_DEBUG
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | if(b>255)
Pike_error("Instruction too big %d\n",b);
|
799039 | 2006-04-27 | Tor Edvardsson | | #endif
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | maybe_update_pc();
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | |
flags = instrs[b].flags;
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | addr=instrs[b].address;
switch(b + F_OFFSET) {
|
b505a7 | 2012-06-13 | Per Hedbor | | case F_DUP:
amd64_load_sp_reg();
|
6785ae | 2012-06-15 | Per Hedbor | | ins_debug_instr_prologue(b, 0, 0);
|
b505a7 | 2012-06-13 | Per Hedbor | | add_reg_imm_reg(sp_reg, -sizeof(struct svalue), REG_R10 );
amd64_push_svaluep( REG_R10 );
return;
|
6785ae | 2012-06-15 | Per Hedbor | |
case F_ADD_INTS:
{
amd64_load_sp_reg();
ins_debug_instr_prologue(b, 0, 0);
mov_mem32_reg( sp_reg, -sizeof(struct svalue)*2, REG_RAX );
shl_reg_imm( REG_RAX, 8 );
mov_mem32_reg( sp_reg,-sizeof(struct svalue), REG_RBX );
add_reg_reg( REG_RAX, REG_RBX );
and_reg_imm( REG_RAX, 0x1f1f );
cmp_reg_imm( REG_RAX, (PIKE_T_INT<<8)|PIKE_T_INT );
jne( &label_A );
mov_mem_reg( sp_reg,
-sizeof(struct svalue)+OFFSETOF(svalue,u.integer),
REG_RAX );
add_reg_mem( REG_RAX,
sp_reg,
-sizeof(struct svalue)*2+OFFSETOF(svalue,u.integer)
);
jo( &label_A );
amd64_add_sp( -1 );
mov_reg_mem( REG_RAX, sp_reg,
-sizeof(struct svalue)+OFFSETOF(svalue,u.integer));
jmp( &label_B );
LABEL_A;
update_arg1( 2 );
amd64_call_c_opcode( f_add, I_UPDATE_SP );
amd64_load_sp_reg();
LABEL_B;
}
return;
|
b505a7 | 2012-06-13 | Per Hedbor | | case F_SWAP:
|
6785ae | 2012-06-15 | Per Hedbor | |
amd64_load_sp_reg();
add_reg_imm_reg( sp_reg, -2*sizeof(struct svalue), REG_R10);
mov_mem_reg( REG_R10, 0, REG_RAX );
mov_mem_reg( REG_R10, 8, REG_RCX );
mov_mem_reg( REG_R10,16, REG_R8 );
mov_mem_reg( REG_R10,24, REG_R9 );
mov_reg_mem(REG_R8, REG_R10,0);
mov_reg_mem(REG_R9, REG_R10,8);
mov_reg_mem(REG_RAX, REG_R10,sizeof(struct svalue));
mov_reg_mem(REG_RCX, REG_R10,8+sizeof(struct svalue));
return;
|
b505a7 | 2012-06-13 | Per Hedbor | | case F_POP_VALUE:
|
6785ae | 2012-06-15 | Per Hedbor | | {
ins_debug_instr_prologue(b, 0, 0);
amd64_load_sp_reg();
amd64_add_sp( -1 );
amd64_free_svalue( sp_reg, 0 );
}
return;
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | case F_CATCH:
|
21b911 | 2011-05-23 | Henrik Grubbström (Grubba) | | {
addr = inter_return_opcode_F_CATCH;
|
719c3a | 2012-06-12 | Per Hedbor | | mov_rip_imm_reg(0, ARG1_REG);
|
48f597 | 2011-05-23 | Henrik Grubbström (Grubba) | | rel_addr = PIKE_PC;
|
21b911 | 2011-05-23 | Henrik Grubbström (Grubba) | | }
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | break;
case F_UNDEFINED:
ins_debug_instr_prologue(b, 0, 0);
amd64_push_int(0, 1);
return;
case F_CONST0:
ins_debug_instr_prologue(b, 0, 0);
amd64_push_int(0, 0);
return;
case F_CONST1:
ins_debug_instr_prologue(b, 0, 0);
amd64_push_int(1, 0);
return;
case F_CONST_1:
ins_debug_instr_prologue(b, 0, 0);
amd64_push_int(-1, 0);
return;
case F_BIGNUM:
ins_debug_instr_prologue(b, 0, 0);
amd64_push_int(0x7fffffff, 0);
return;
case F_RETURN_1:
ins_f_byte(F_CONST1);
ins_f_byte(F_RETURN);
return;
case F_RETURN_0:
ins_f_byte(F_CONST0);
ins_f_byte(F_RETURN);
return;
case F_ADD:
ins_debug_instr_prologue(b, 0, 0);
update_arg1(2);
addr = f_add;
break;
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | case F_MARK:
case F_SYNCH_MARK:
ins_debug_instr_prologue(b, 0, 0);
amd64_mark(0);
return;
case F_MARK2:
ins_f_byte(F_MARK);
ins_f_byte(F_MARK);
return;
|
91080b | 2012-06-15 | Henrik Grubbström (Grubba) | | case F_MARK_AND_CONST0:
ins_f_byte(F_MARK);
ins_f_byte(F_CONST0);
return;
case F_MARK_AND_CONST1:
ins_f_byte(F_MARK);
ins_f_byte(F_CONST1);
return;
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | case F_POP_MARK:
ins_debug_instr_prologue(b, 0, 0);
amd64_pop_mark();
return;
|
9853bd | 2012-06-13 | Henrik Grubbström (Grubba) | | case F_POP_TO_MARK:
ins_debug_instr_prologue(b, 0, 0);
amd64_load_mark_sp_reg();
amd64_load_sp_reg();
amd64_pop_mark();
mov_mem_reg(mark_sp_reg, 0, REG_RBX);
jmp(&label_A);
LABEL_B;
amd64_add_sp( -1 );
amd64_free_svalue( sp_reg, 0 );
LABEL_A;
cmp_reg_reg(REG_RBX, sp_reg);
jl(&label_B);
return;
|
6785ae | 2012-06-15 | Per Hedbor | | #ifndef PIKE_DEBUG
case F_RETURN:
#endif
case F_DUMB_RETURN:
{
LABELS();
amd64_load_fp_reg();
mov_mem32_reg( fp_reg, OFFSETOF(pike_frame, flags), REG_RAX );
and_reg_imm( REG_RAX, PIKE_FRAME_RETURN_INTERNAL);
jnz( &label_A );
LABEL_B;
flush_dirty_regs();
amd64_return_from_function();
LABEL_A;
amd64_call_c_opcode(addr,flags);
#if 0
cmp_reg_imm(REG_RAX, -1);
je(&label_B);
#endif
jmp_reg(REG_RAX);
}
return;
|
91080b | 2012-06-15 | Henrik Grubbström (Grubba) | | case F_CLEAR_STRING_SUBTYPE:
ins_debug_instr_prologue(b, 0, 0);
amd64_load_sp_reg();
mov_mem32_reg(sp_reg, OFFSETOF(svalue, type) - sizeof(struct svalue),
REG_RAX);
cmp_reg_imm(REG_RAX, (1<<16)|PIKE_T_STRING);
jne(&label_A);
and_reg_imm(REG_RAX, 0x1f);
mov_reg_mem32(REG_RAX,
sp_reg, OFFSETOF(svalue, type) - sizeof(struct svalue));
LABEL_A;
return;
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | }
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_call_c_opcode(addr,flags);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | |
if (instrs[b].flags & I_RETURN) {
|
719c3a | 2012-06-12 | Per Hedbor | | LABELS();
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | if ((b + F_OFFSET) == F_RETURN_IF_TRUE) {
|
719c3a | 2012-06-12 | Per Hedbor | | * PC + JUMP_EPILOGUE_SIZE. */
mov_rip_imm_reg(JUMP_EPILOGUE_SIZE, REG_RCX);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | }
|
719c3a | 2012-06-12 | Per Hedbor | | cmp_reg_imm(REG_RAX, -1);
|
6785ae | 2012-06-15 | Per Hedbor | | jne(&label_A);
amd64_return_from_function();
|
719c3a | 2012-06-12 | Per Hedbor | | LABEL_A;
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | if ((b + F_OFFSET) == F_RETURN_IF_TRUE) {
|
719c3a | 2012-06-12 | Per Hedbor | | cmp_reg_reg( REG_RAX, REG_RCX );
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | je( &label_B );
|
719c3a | 2012-06-12 | Per Hedbor | | jmp_reg(REG_RAX);
|
15e8a0 | 2012-06-13 | Henrik Grubbström (Grubba) | | LABEL_B;
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | return;
}
}
|
f78425 | 2011-05-11 | Henrik Grubbström (Grubba) | | if (flags & I_JUMP) {
|
719c3a | 2012-06-12 | Per Hedbor | | jmp_reg(REG_RAX);
|
48f597 | 2011-05-23 | Henrik Grubbström (Grubba) | |
if (b + F_OFFSET == F_CATCH) {
upd_pointer(rel_addr - 4, PIKE_PC - rel_addr);
}
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | }
|
799039 | 2006-04-27 | Tor Edvardsson | | }
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | int amd64_ins_f_jump(unsigned int op, int backward_jump)
{
int flags;
void *addr;
int off = op - F_OFFSET;
int ret = -1;
|
b505a7 | 2012-06-13 | Per Hedbor | | LABELS();
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if(off>255)
Pike_error("Instruction too big %d\n",off);
#endif
flags = instrs[off].flags;
if (!(flags & I_BRANCH)) return -1;
|
6785ae | 2012-06-15 | Per Hedbor | | #define START_JUMP() do{ \
ins_debug_instr_prologue(off, 0, 0); \
if (backward_jump) { \
maybe_update_pc(); \
amd64_ins_branch_check_threads_etc(); \
} \
} while(0)
|
b505a7 | 2012-06-13 | Per Hedbor | | switch( op )
{
|
99c1e9 | 2012-06-20 | Per Hedbor | | case F_QUICK_BRANCH_WHEN_ZERO:
case F_QUICK_BRANCH_WHEN_NON_ZERO:
START_JUMP();
amd64_load_sp_reg();
amd64_add_sp( -1 );
mov_mem_reg( sp_reg, 8, REG_RAX );
test_reg(REG_RAX);
if( op == F_QUICK_BRANCH_WHEN_ZERO )
return jz_imm_rel32(0);
return jnz_imm_rel32(0);
case F_BRANCH_WHEN_ZERO:
case F_BRANCH_WHEN_NON_ZERO:
START_JUMP();
amd64_load_sp_reg();
mov_mem16_reg( sp_reg, -sizeof(struct svalue), REG_RAX );
cmp_reg_imm( REG_RAX, PIKE_T_OBJECT );
je( &label_A );
amd64_add_sp( -1 );
mov_mem_reg( sp_reg, 8, REG_RBX );
amd64_free_svalue_type( sp_reg, REG_RAX, 0 );
test_reg( REG_RBX );
jmp( &label_B );
LABEL_A;
amd64_call_c_opcode(instrs[F_BRANCH_WHEN_ZERO-F_OFFSET].address,
instrs[F_BRANCH_WHEN_ZERO-F_OFFSET].flags );
cmp_reg_imm( REG_RAX, -1 );
LABEL_B;
if( op == F_BRANCH_WHEN_ZERO )
return jz_imm_rel32(0);
return jnz_imm_rel32(0);
|
b505a7 | 2012-06-13 | Per Hedbor | | case F_LOOP:
|
6785ae | 2012-06-15 | Per Hedbor | |
START_JUMP();
amd64_load_sp_reg();
mov_mem32_reg( sp_reg, -sizeof(struct svalue), REG_RAX );
cmp_reg_imm( REG_RAX, PIKE_T_INT );
jne( &label_A );
mov_mem_reg( sp_reg, -sizeof(struct svalue)+8, REG_RAX );
test_reg(REG_RAX);
jz( &label_B );
add_reg_imm( REG_RAX, -1 );
mov_reg_mem( REG_RAX, sp_reg, -sizeof(struct svalue)+8);
mov_imm_reg( 1, REG_RAX );
jmp( &label_C );
|
b505a7 | 2012-06-13 | Per Hedbor | |
LABEL_A;
|
6785ae | 2012-06-15 | Per Hedbor | | amd64_call_c_opcode(instrs[F_LOOP-F_OFFSET].address,
instrs[F_LOOP-F_OFFSET].flags );
jmp( &label_C );
|
b505a7 | 2012-06-13 | Per Hedbor | |
|
6785ae | 2012-06-15 | Per Hedbor | |
|
b505a7 | 2012-06-13 | Per Hedbor | | LABEL_B;
|
6785ae | 2012-06-15 | Per Hedbor | | amd64_add_sp( -1 );
mov_imm_reg(0, REG_RAX );
|
b505a7 | 2012-06-13 | Per Hedbor | |
LABEL_C;
|
6785ae | 2012-06-15 | Per Hedbor | | test_reg( REG_RAX );
return jnz_imm_rel32(0);
case F_BRANCH_WHEN_EQ:
case F_BRANCH_WHEN_NE:
amd64_load_sp_reg();
mov_mem16_reg( sp_reg, -sizeof(struct svalue), REG_RAX );
mov_mem16_reg( sp_reg, -sizeof(struct svalue)*2,REG_RBX );
cmp_reg_reg( REG_RAX, REG_RBX );
jnz( &label_A );
cmp_reg_imm( REG_RAX, PIKE_T_OBJECT );
je( &label_A );
mov_mem_reg( sp_reg, -sizeof(struct svalue)+8, REG_RBX );
sub_reg_mem( REG_RBX, sp_reg, -sizeof(struct svalue)*2+8);
cmp_reg_imm( REG_RAX,MAX_REF_TYPE+1);
jl( &label_B );
amd64_add_sp( -2 );
jmp( &label_D );
LABEL_A;
amd64_call_c_opcode( instrs[F_BRANCH_WHEN_NE-F_OFFSET].address,
instrs[F_BRANCH_WHEN_NE-F_OFFSET].flags );
amd64_load_sp_reg();
mov_reg_reg(REG_RAX, REG_RBX);
jmp(&label_D);
LABEL_B;
amd64_add_sp( -2 );
mov_mem_reg( sp_reg, OFFSETOF(svalue,u.refs), REG_RAX );
add_mem32_imm( REG_RAX, OFFSETOF(pike_string,refs), -1 );
jnz( &label_C );
mov_reg_reg( sp_reg, ARG1_REG );
amd64_call_c_function( really_free_svalue );
LABEL_C;
add_reg_imm_reg( sp_reg, sizeof(struct svalue), ARG1_REG );
mov_mem_reg( ARG1_REG, OFFSETOF(svalue,u.refs), REG_RAX );
add_mem32_imm( REG_RAX, OFFSETOF(pike_string,refs), -1 );
jnz( &label_D );
amd64_call_c_function( really_free_svalue );
LABEL_D;
test_reg(REG_RBX);
if( op == F_BRANCH_WHEN_EQ )
return jz_imm_rel32(0);
return jnz_imm_rel32(0);
#if 0
case F_BRANCH_WHEN_LT:
case F_BRANCH_WHEN_GE:
case F_BRANCH_WHEN_GT:
case F_BRANCH_WHEN_LE:
#endif
case F_BRANCH:
START_JUMP();
add_to_program(0xe9);
ret=DO_NOT_WARN( (INT32) PIKE_PC );
PUSH_INT(0);
return ret;
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | }
|
719c3a | 2012-06-12 | Per Hedbor | | maybe_update_pc();
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | addr=instrs[off].address;
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_call_c_opcode(addr, flags);
|
6785ae | 2012-06-15 | Per Hedbor | | amd64_load_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | test_reg(REG_RAX);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | |
if (backward_jump) {
|
48f597 | 2011-05-23 | Henrik Grubbström (Grubba) | | INT32 skip;
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | add_to_program (0x74);
|
48f597 | 2011-05-23 | Henrik Grubbström (Grubba) | | add_to_program (0);
skip = (INT32)PIKE_PC;
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_ins_branch_check_threads_etc();
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | add_to_program (0xe9);
ret = DO_NOT_WARN ((INT32) PIKE_PC);
|
48f597 | 2011-05-23 | Henrik Grubbström (Grubba) | | PUSH_INT (0);
Pike_compiler->new_program->program[skip-1] = ((INT32)PIKE_PC - skip);
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | }
else {
add_to_program (0x0f);
add_to_program (0x85);
ret = DO_NOT_WARN ((INT32) PIKE_PC);
PUSH_INT (0);
}
return ret;
}
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | void ins_f_byte_with_arg(unsigned int a, INT32 b)
{
maybe_update_pc();
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | switch(a) {
|
719c3a | 2012-06-12 | Per Hedbor | | case F_THIS_OBJECT:
if( b == 0 )
{
amd64_push_this_object();
return;
}
|
1c1a24 | 2012-06-13 | Henrik Grubbström (Grubba) | | break;
|
6785ae | 2012-06-15 | Per Hedbor | |
case F_ADD_NEG_INT:
b = -b;
case F_ADD_INT:
{
LABELS();
amd64_load_sp_reg();
mov_mem16_reg( sp_reg, -sizeof(struct svalue), REG_RAX );
cmp_reg_imm( REG_RAX,PIKE_T_INT );
jne( &label_A );
mov_mem_reg(sp_reg,
-sizeof(struct svalue)+OFFSETOF(svalue,u.integer),
REG_RAX );
add_reg_imm( REG_RAX, b );
jo( &label_A );
mov_reg_mem( REG_RAX,sp_reg,
-sizeof(struct svalue)+OFFSETOF(svalue,u.integer));
jmp(&label_B);
LABEL_A;
amd64_push_int(b,0);
update_arg1(2);
amd64_call_c_opcode( f_add, I_UPDATE_SP );
amd64_load_sp_reg();
LABEL_B;
}
return;
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | case F_NUMBER:
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | ins_debug_instr_prologue(a-F_OFFSET, b, 0);
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | amd64_push_int(b, 0);
return;
case F_NEG_NUMBER:
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | ins_debug_instr_prologue(a-F_OFFSET, b, 0);
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | amd64_push_int(-(INT64)b, 0);
return;
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | case F_STRING:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_push_string(b, 0);
return;
case F_ARROW_STRING:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_push_string(b, 1);
return;
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | case F_POS_INT_INDEX:
ins_f_byte_with_arg(F_NUMBER, b);
ins_f_byte(F_INDEX);
return;
case F_NEG_INT_INDEX:
ins_f_byte_with_arg(F_NEG_NUMBER, b);
ins_f_byte(F_INDEX);
return;
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | case F_MARK_AND_CONST0:
ins_f_byte(F_MARK);
ins_f_byte(F_CONST0);
return;
case F_MARK_AND_CONST1:
ins_f_byte(F_MARK);
ins_f_byte(F_CONST0);
return;
case F_MARK_AND_STRING:
ins_f_byte(F_MARK);
ins_f_byte_with_arg(F_STRING, b);
return;
case F_MARK_AND_GLOBAL:
ins_f_byte(F_MARK);
ins_f_byte_with_arg(F_GLOBAL, b);
return;
case F_MARK_AND_LOCAL:
ins_f_byte(F_MARK);
ins_f_byte_with_arg(F_LOCAL, b);
return;
case F_MARK_X:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_mark(b);
return;
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | case F_LFUN:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_push_local_function(b);
return;
|
719c3a | 2012-06-12 | Per Hedbor | |
case F_ASSIGN_LOCAL:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
|
fd1b5a | 2012-06-19 | Henrik Grubbström (Grubba) | | amd64_load_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_assign_local(b);
add_reg_imm_reg(sp_reg, -sizeof(struct svalue), ARG1_REG);
|
b505a7 | 2012-06-13 | Per Hedbor | | amd64_ref_svalue(ARG1_REG, 0);
|
719c3a | 2012-06-12 | Per Hedbor | | return;
case F_ASSIGN_LOCAL_AND_POP:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_assign_local(b);
amd64_add_sp(-1);
return;
case F_ASSIGN_GLOBAL:
case F_ASSIGN_GLOBAL_AND_POP:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
amd64_load_sp_reg();
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, current_object), ARG1_REG);
mov_mem_reg(fp_reg, OFFSETOF(pike_frame,context), ARG2_REG);
mov_mem16_reg(ARG2_REG, OFFSETOF(inherit, identifier_level), ARG2_REG);
add_reg_imm( ARG2_REG, b );
add_reg_imm_reg( sp_reg, -sizeof(struct svalue), ARG3_REG );
amd64_call_c_function( object_low_set_index );
if( a == F_ASSIGN_GLOBAL_AND_POP )
{
amd64_add_sp( -1 );
amd64_free_svalue( sp_reg, 1 );
}
return;
case F_SIZEOF_LOCAL:
{
LABELS();
|
5c82f4 | 2012-06-13 | Henrik Grubbström (Grubba) | | ins_debug_instr_prologue(a-F_OFFSET, b, 0);
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_load_fp_reg();
amd64_load_sp_reg();
mov_mem_reg( fp_reg, OFFSETOF(pike_frame,locals), ARG1_REG);
add_reg_imm( ARG1_REG, b*sizeof(struct svalue));
#if 0
mov_sval_type( ARG1_REG, REG_RAX );
cmp_reg_imm( REG_RAX, PIKE_T_ARRAY );
jne( &label_A );
mov_mem_reg( ARG1_REG, OFFSETOF(svalue, u.array ), ARG1_REG);
mov_mem32_reg( ARG1_REG,OFFSETOF(array, size), REG_RAX );
jmp( &label_C );
LABEL_A;
cmp_reg_imm( REG_RAX, PIKE_T_STRING );
jne( &label_B );
mov_mem_reg( ARG1_REG, OFFSETOF(svalue, u.string ), ARG1_REG);
mov_mem32_reg( ARG1_REG,OFFSETOF(pike_string, len ), REG_RAX );
jmp( &label_C );
LABEL_B;
#endif
amd64_call_c_function( pike_sizeof );
amd64_load_sp_reg();
LABEL_C;
amd64_push_int_reg( REG_RAX );
}
return;
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | case F_GLOBAL:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
amd64_load_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(fp_reg, OFFSETOF(pike_frame, context), ARG3_REG);
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, current_object),
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | ARG2_REG);
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_reg(sp_reg, ARG1_REG);
mov_mem32_reg(ARG3_REG, OFFSETOF(inherit, identifier_level),
ARG3_REG);
and_reg_imm(ARG3_REG, 0xffff);
add_reg_imm(ARG3_REG, b);
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | flush_dirty_regs();
|
719c3a | 2012-06-12 | Per Hedbor | | call_imm(low_object_index_no_free);
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | |
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_add_sp(1);
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | return;
|
719c3a | 2012-06-12 | Per Hedbor | |
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | case F_LOCAL:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
amd64_load_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), REG_RCX);
add_reg_imm(REG_RCX, b*sizeof(struct svalue));
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | amd64_push_svaluep(REG_RCX);
return;
|
719c3a | 2012-06-12 | Per Hedbor | |
|
91080b | 2012-06-15 | Henrik Grubbström (Grubba) | | case F_CLEAR_LOCAL:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), REG_RBX);
add_reg_imm(REG_RBX, b*sizeof(struct svalue));
amd64_free_svalue(REG_RBX, 0);
mov_imm_mem(0, REG_RBX, OFFSETOF(svalue, u.integer));
mov_imm_mem32(PIKE_T_INT, REG_RBX, OFFSETOF(svalue, type));
return;
case F_INC_LOCAL_AND_POP:
{
LABELS();
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), REG_RCX);
add_reg_imm(REG_RCX, b*sizeof(struct svalue));
mov_sval_type(REG_RCX, REG_RAX);
cmp_reg_imm(REG_RAX, PIKE_T_INT);
jne(&label_A);
mov_reg_mem32(REG_RAX, REG_RCX, OFFSETOF(svalue, type));
add_imm_mem(1, REG_RCX, OFFSETOF(svalue, u.integer));
|
ec9691 | 2012-06-17 | Henrik Grubbström (Grubba) | | jno(&label_B);
|
91080b | 2012-06-15 | Henrik Grubbström (Grubba) | | add_imm_mem(-1, REG_RCX, OFFSETOF(svalue, u.integer));
LABEL_A;
update_arg1(b);
amd64_call_c_opcode(instrs[a-F_OFFSET].address,
instrs[a-F_OFFSET].flags);
LABEL_B;
}
return;
|
b66959 | 2012-06-19 | Henrik Grubbström (Grubba) | | case F_INC_LOCAL:
ins_f_byte_with_arg(F_INC_LOCAL_AND_POP, b);
ins_f_byte_with_arg(F_LOCAL, b);
return;
case F_POST_INC_LOCAL:
ins_f_byte_with_arg(F_LOCAL, b);
ins_f_byte_with_arg(F_INC_LOCAL_AND_POP, b);
return;
|
91080b | 2012-06-15 | Henrik Grubbström (Grubba) | | case F_DEC_LOCAL_AND_POP:
{
LABELS();
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), REG_RCX);
add_reg_imm(REG_RCX, b*sizeof(struct svalue));
mov_sval_type(REG_RCX, REG_RAX);
cmp_reg_imm(REG_RAX, PIKE_T_INT);
jne(&label_A);
|
ec9691 | 2012-06-17 | Henrik Grubbström (Grubba) | | mov_reg_mem32(REG_RAX, REG_RCX, OFFSETOF(svalue, type));
|
91080b | 2012-06-15 | Henrik Grubbström (Grubba) | | add_imm_mem(-1, REG_RCX, OFFSETOF(svalue, u.integer));
|
ec9691 | 2012-06-17 | Henrik Grubbström (Grubba) | | jno(&label_B);
|
91080b | 2012-06-15 | Henrik Grubbström (Grubba) | | add_imm_mem(1, REG_RCX, OFFSETOF(svalue, u.integer));
LABEL_A;
update_arg1(b);
amd64_call_c_opcode(instrs[a-F_OFFSET].address,
instrs[a-F_OFFSET].flags);
LABEL_B;
}
return;
|
b66959 | 2012-06-19 | Henrik Grubbström (Grubba) | | case F_DEC_LOCAL:
ins_f_byte_with_arg(F_DEC_LOCAL_AND_POP, b);
ins_f_byte_with_arg(F_LOCAL, b);
return;
case F_POST_DEC_LOCAL:
ins_f_byte_with_arg(F_LOCAL, b);
ins_f_byte_with_arg(F_DEC_LOCAL_AND_POP, b);
return;
|
719c3a | 2012-06-12 | Per Hedbor | | case F_CONSTANT:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
amd64_load_sp_reg();
mov_mem_reg( fp_reg, OFFSETOF(pike_frame,context), REG_RCX );
mov_mem_reg( REG_RCX, OFFSETOF(inherit,prog), REG_RCX );
mov_mem_reg( REG_RCX, OFFSETOF(program,constants), REG_RCX );
add_reg_imm( REG_RCX, b*sizeof(struct program_constant) +
OFFSETOF(program_constant,sval) );
amd64_push_svaluep( REG_RCX );
return;
case F_GLOBAL_LVALUE:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
amd64_load_sp_reg();
amd64_push_this_object( );
mov_imm_mem( T_OBJ_INDEX, sp_reg, OFFSETOF(svalue,type));
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, context), REG_RAX);
mov_mem16_reg( REG_RAX,OFFSETOF(inherit, identifier_level), REG_RAX);
add_reg_imm( REG_RAX, b );
mov_reg_mem( REG_RAX, sp_reg, OFFSETOF(svalue,u.identifier) );
amd64_add_sp( 1 );
return;
case F_LOCAL_LVALUE:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
amd64_load_sp_reg();
mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), REG_RAX);
add_reg_imm( REG_RAX, b*sizeof(struct svalue));
mov_imm_mem( T_SVALUE_PTR, sp_reg, OFFSETOF(svalue,type));
mov_reg_mem( REG_RAX, sp_reg, OFFSETOF(svalue,u.lval) );
mov_imm_mem( T_VOID, sp_reg, OFFSETOF(svalue,type)+sizeof(struct svalue));
amd64_add_sp( 2 );
return;
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | case F_PROTECT_STACK:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | if (b) {
|
719c3a | 2012-06-12 | Per Hedbor | | add_reg_imm_reg(ARG1_REG, sizeof(struct svalue) * b, ARG1_REG);
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | }
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_mem(ARG1_REG, fp_reg,
OFFSETOF(pike_frame, expendible));
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | return;
case F_MARK_AT:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();
amd64_load_mark_sp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | | mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | if (b) {
|
719c3a | 2012-06-12 | Per Hedbor | | add_reg_imm_reg(ARG1_REG, sizeof(struct svalue) * b, ARG1_REG);
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | }
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_mem(ARG1_REG, mark_sp_reg, 0x00);
add_reg_imm(mark_sp_reg, sizeof(struct svalue *));
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | dirty_regs |= 1 << mark_sp_reg;
if (dirty_regs & (1 << PIKE_MARK_SP_REG)) {
|
719c3a | 2012-06-12 | Per Hedbor | | mov_reg_mem(PIKE_MARK_SP_REG, Pike_interpreter_reg,
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | OFFSETOF(Pike_interpreter_struct, mark_stack_pointer));
dirty_regs &= ~(1 << PIKE_MARK_SP_REG);
}
return;
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | }
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | update_arg1(b);
ins_f_byte(a);
|
799039 | 2006-04-27 | Tor Edvardsson | | }
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | int amd64_ins_f_jump_with_arg(unsigned int op, INT32 a, int backward_jump)
{
|
719c3a | 2012-06-12 | Per Hedbor | | LABELS();
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | if (!(instrs[op - F_OFFSET].flags & I_BRANCH)) return -1;
|
719c3a | 2012-06-12 | Per Hedbor | |
switch( op )
{
case F_BRANCH_IF_NOT_LOCAL:
case F_BRANCH_IF_LOCAL:
ins_debug_instr_prologue(op-F_OFFSET, a, 0);
amd64_load_fp_reg();
mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), REG_RAX);
add_reg_imm( REG_RAX, a*sizeof(struct svalue));
mov_sval_type( REG_RAX, REG_RCX );
cmp_reg_imm( REG_RCX, PIKE_T_OBJECT );
jne( &label_A );
update_arg1(a);
amd64_call_c_opcode( instrs[F_BRANCH_IF_LOCAL-F_OFFSET].address,
instrs[F_BRANCH_IF_LOCAL-F_OFFSET].flags );
jmp( &label_B );
LABEL_A;
mov_mem_reg( REG_RAX, OFFSETOF(svalue, u.integer ), REG_RAX );
LABEL_B;
test_reg( REG_RAX );
if( op == F_BRANCH_IF_LOCAL )
return jnz_imm_rel32(0);
return jz_imm_rel32(0);
}
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | maybe_update_pc();
update_arg1(a);
return amd64_ins_f_jump(op, backward_jump);
}
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | void ins_f_byte_with_2_args(unsigned int a, INT32 b, INT32 c)
{
maybe_update_pc();
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | switch(a) {
case F_NUMBER64:
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | ins_debug_instr_prologue(a-F_OFFSET, b, c);
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | amd64_push_int((((unsigned INT64)b)<<32)|(unsigned INT32)c, 0);
return;
|
ab7cf5 | 2011-05-24 | Henrik Grubbström (Grubba) | | case F_MARK_AND_EXTERNAL:
ins_f_byte(F_MARK);
ins_f_byte_with_2_args(F_EXTERNAL, b, c);
return;
|
f4107d | 2012-06-18 | Per Hedbor | |
case F_ADD_LOCAL_INT_AND_POP:
{
LABELS();
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
|
fd1b5a | 2012-06-19 | Henrik Grubbström (Grubba) | | amd64_load_fp_reg();
|
f4107d | 2012-06-18 | Per Hedbor | | mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);
add_reg_imm( ARG1_REG, b*sizeof(struct svalue) );
mov_sval_type( ARG1_REG, REG_RAX );
cmp_reg_imm( REG_RAX, PIKE_T_INT );
jne(&label_A);
add_imm_mem( c, ARG1_REG,OFFSETOF(svalue,u.integer));
jno( &label_B);
add_imm_mem( -c, ARG1_REG,OFFSETOF(svalue,u.integer));
LABEL_A;
update_arg2(c);
update_arg1(b);
ins_f_byte(a);
LABEL_B;
return;
}
case F_ADD_LOCALS_AND_POP:
{
LABELS();
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
|
fd1b5a | 2012-06-19 | Henrik Grubbström (Grubba) | | amd64_load_fp_reg();
|
f4107d | 2012-06-18 | Per Hedbor | | mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);
add_reg_imm( ARG1_REG, b*sizeof(struct svalue) );
add_reg_imm_reg( ARG1_REG,(c-b)*sizeof(struct svalue), ARG2_REG );
mov_sval_type( ARG1_REG, REG_RAX );
mov_sval_type( ARG2_REG, REG_RBX );
shl_reg_imm( REG_RAX, 8 );
add_reg_reg( REG_RAX, REG_RBX );
cmp_reg_imm( REG_RAX, (PIKE_T_INT<<8) | PIKE_T_INT );
jne(&label_A);
mov_mem_reg( ARG2_REG, OFFSETOF(svalue,u.integer), REG_RAX );
add_reg_mem( REG_RAX, ARG1_REG, OFFSETOF(svalue,u.integer));
jo( &label_A);
mov_imm_mem( PIKE_T_INT, ARG1_REG,OFFSETOF(svalue,type));
mov_reg_mem( REG_RAX, ARG1_REG, OFFSETOF(svalue,u.integer));
jmp( &label_B );
LABEL_A;
update_arg2(c);
update_arg1(b);
ins_f_byte(a);
LABEL_B;
return;
}
case F_ASSIGN_LOCAL_NUMBER_AND_POP:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
|
fd1b5a | 2012-06-19 | Henrik Grubbström (Grubba) | | amd64_load_fp_reg();
|
f4107d | 2012-06-18 | Per Hedbor | | mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);
add_reg_imm( ARG1_REG,b*sizeof(struct svalue) );
mov_reg_reg( ARG1_REG, REG_RBX );
amd64_free_svalue(ARG1_REG, 0);
mov_imm_mem(c, REG_RBX, OFFSETOF(svalue, u.integer));
mov_imm_mem32(PIKE_T_INT, REG_RBX, OFFSETOF(svalue, type));
return;
|
b505a7 | 2012-06-13 | Per Hedbor | | case F_LOCAL_2_LOCAL:
|
5c82f4 | 2012-06-13 | Henrik Grubbström (Grubba) | | ins_debug_instr_prologue(a-F_OFFSET, b, c);
|
b505a7 | 2012-06-13 | Per Hedbor | | if( b != c )
{
amd64_load_fp_reg();
|
373ff5 | 2012-06-13 | Henrik Grubbström (Grubba) | | mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), REG_RBX );
add_reg_imm( REG_RBX, b*sizeof(struct svalue) );
|
b505a7 | 2012-06-13 | Per Hedbor | |
amd64_free_svalue( REG_RBX, 0 );
|
373ff5 | 2012-06-13 | Henrik Grubbström (Grubba) | |
|
b505a7 | 2012-06-13 | Per Hedbor | | mov_mem_reg( REG_RBX, (c-b)*sizeof(struct svalue), REG_RAX );
mov_mem_reg( REG_RBX, (c-b)*sizeof(struct svalue)+8, REG_RCX );
mov_reg_mem( REG_RAX, REG_RBX, 0 );
mov_reg_mem( REG_RCX, REG_RBX, 8 );
amd64_ref_svalue( REG_RBX, 1 );
}
return;
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | case F_2_LOCALS:
|
719c3a | 2012-06-12 | Per Hedbor | | #if 1
|
5c82f4 | 2012-06-13 | Henrik Grubbström (Grubba) | | ins_debug_instr_prologue(a-F_OFFSET, b, c);
|
719c3a | 2012-06-12 | Per Hedbor | | amd64_load_fp_reg();
amd64_load_sp_reg();
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), REG_R8);
add_reg_imm( REG_R8, b*sizeof(struct svalue) );
amd64_push_svaluep(REG_R8);
add_reg_imm( REG_R8, (c-b)*sizeof(struct svalue) );
amd64_push_svaluep(REG_R8);
#else
ins_f_byte_with_arg( F_LOCAL, b );
ins_f_byte_with_arg( F_LOCAL, c );
#endif
|
9030f6 | 2011-05-26 | Henrik Grubbström (Grubba) | | return;
|
719c3a | 2012-06-12 | Per Hedbor | |
|
9853bd | 2012-06-13 | Henrik Grubbström (Grubba) | | case F_FILL_STACK:
{
LABELS();
if (!b) return;
ins_debug_instr_prologue(a-F_OFFSET, b, c);
amd64_load_fp_reg();
amd64_load_sp_reg();
mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);
add_reg_imm(ARG1_REG, b*sizeof(struct svalue));
jmp(&label_A);
LABEL_B;
amd64_push_int(0, c);
LABEL_A;
cmp_reg_reg(sp_reg, ARG1_REG);
jge(&label_B);
}
return;
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | case F_INIT_FRAME:
ins_debug_instr_prologue(a-F_OFFSET, b, c);
amd64_load_fp_reg();
|
719c3a | 2012-06-12 | Per Hedbor | |
if(OFFSETOF(pike_frame, num_locals) != OFFSETOF(pike_frame, num_args)-2 )
Pike_fatal("This code does not with unless num_args\n"
"directly follows num_locals in struct pike_frame\n");
mov_imm_mem32( (b<<16)|c, fp_reg, OFFSETOF(pike_frame, num_locals));
|
5151e5 | 2012-06-10 | Henrik Grubbström (Grubba) | | return;
|
eb42a1 | 2011-05-11 | Henrik Grubbström (Grubba) | | }
|
d1fa80 | 2011-05-09 | Henrik Grubbström (Grubba) | | update_arg2(c);
update_arg1(b);
ins_f_byte(a);
|
799039 | 2006-04-27 | Tor Edvardsson | | }
|
54a26b | 2011-05-11 | Henrik Grubbström (Grubba) | | int amd64_ins_f_jump_with_2_args(unsigned int op, INT32 a, INT32 b,
int backward_jump)
{
if (!(instrs[op - F_OFFSET].flags & I_BRANCH)) return -1;
maybe_update_pc();
update_arg2(b);
update_arg1(a);
return amd64_ins_f_jump(op, backward_jump);
}
void amd64_update_f_jump(INT32 offset, INT32 to_offset)
{
upd_pointer(offset, to_offset - offset - 4);
}
INT32 amd64_read_f_jump(INT32 offset)
{
return read_pointer(offset) + offset + 4;
}
|