mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
6797305: Add LoadUB and LoadUI opcode class
Add a LoadUB (unsigned byte) and LoadUI (unsigned int) opcode class so we have these load optimizations in the first place and do not need to handle them in the matcher. Reviewed-by: never, kvn
This commit is contained in:
parent
26d192003f
commit
89cea91c48
17 changed files with 726 additions and 186 deletions
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
// Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -5286,55 +5286,91 @@ instruct loadB(iRegI dst, memory mem) %{
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
size(4);
|
size(4);
|
||||||
format %{ "LDSB $mem,$dst" %}
|
format %{ "LDSB $mem,$dst\t! byte" %}
|
||||||
opcode(Assembler::ldsb_op3);
|
opcode(Assembler::ldsb_op3);
|
||||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Byte (8bit UNsigned) into an int reg
|
// Load Byte (8bit signed) into a Long Register
|
||||||
instruct loadUB(iRegI dst, memory mem, immI_255 bytemask) %{
|
instruct loadB2L(iRegL dst, memory mem) %{
|
||||||
match(Set dst (AndI (LoadB mem) bytemask));
|
match(Set dst (ConvI2L (LoadB mem)));
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUB $mem,$dst" %}
|
format %{ "LDSB $mem,$dst\t! byte -> long" %}
|
||||||
|
opcode(Assembler::ldsb_op3);
|
||||||
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
|
ins_pipe(iload_mask_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Byte (8bit UNsigned) into an int reg
|
||||||
|
instruct loadUB(iRegI dst, memory mem) %{
|
||||||
|
match(Set dst (LoadUB mem));
|
||||||
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "LDUB $mem,$dst\t! ubyte" %}
|
||||||
opcode(Assembler::ldub_op3);
|
opcode(Assembler::ldub_op3);
|
||||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Byte (8bit UNsigned) into a Long Register
|
// Load Unsigned Byte (8bit UNsigned) into a Long Register
|
||||||
instruct loadUBL(iRegL dst, memory mem, immL_FF bytemask) %{
|
instruct loadUB2L(iRegL dst, memory mem) %{
|
||||||
match(Set dst (AndL (ConvI2L (LoadB mem)) bytemask));
|
match(Set dst (ConvI2L (LoadUB mem)));
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUB $mem,$dst" %}
|
format %{ "LDUB $mem,$dst\t! ubyte -> long" %}
|
||||||
opcode(Assembler::ldub_op3);
|
opcode(Assembler::ldub_op3);
|
||||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
|
// Load Short (16bit signed)
|
||||||
instruct loadUS2L(iRegL dst, memory mem, immL_FFFF bytemask) %{
|
instruct loadS(iRegI dst, memory mem) %{
|
||||||
match(Set dst (AndL (ConvI2L (LoadUS mem)) bytemask));
|
match(Set dst (LoadS mem));
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUH $mem,$dst" %}
|
format %{ "LDSH $mem,$dst\t! short" %}
|
||||||
opcode(Assembler::lduh_op3);
|
opcode(Assembler::ldsh_op3);
|
||||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Unsigned Short/Char (16bit unsigned)
|
// Load Short (16bit signed) into a Long Register
|
||||||
|
instruct loadS2L(iRegL dst, memory mem) %{
|
||||||
|
match(Set dst (ConvI2L (LoadS mem)));
|
||||||
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "LDSH $mem,$dst\t! short -> long" %}
|
||||||
|
opcode(Assembler::ldsh_op3);
|
||||||
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
|
ins_pipe(iload_mask_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Short/Char (16bit UNsigned)
|
||||||
instruct loadUS(iRegI dst, memory mem) %{
|
instruct loadUS(iRegI dst, memory mem) %{
|
||||||
match(Set dst (LoadUS mem));
|
match(Set dst (LoadUS mem));
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUH $mem,$dst" %}
|
format %{ "LDUH $mem,$dst\t! ushort/char" %}
|
||||||
|
opcode(Assembler::lduh_op3);
|
||||||
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
|
ins_pipe(iload_mask_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
|
||||||
|
instruct loadUS2L(iRegL dst, memory mem) %{
|
||||||
|
match(Set dst (ConvI2L (LoadUS mem)));
|
||||||
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "LDUH $mem,$dst\t! ushort/char -> long" %}
|
||||||
opcode(Assembler::lduh_op3);
|
opcode(Assembler::lduh_op3);
|
||||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
|
@ -5344,9 +5380,33 @@ instruct loadUS(iRegI dst, memory mem) %{
|
||||||
instruct loadI(iRegI dst, memory mem) %{
|
instruct loadI(iRegI dst, memory mem) %{
|
||||||
match(Set dst (LoadI mem));
|
match(Set dst (LoadI mem));
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
size(4);
|
|
||||||
|
|
||||||
format %{ "LDUW $mem,$dst" %}
|
size(4);
|
||||||
|
format %{ "LDUW $mem,$dst\t! int" %}
|
||||||
|
opcode(Assembler::lduw_op3);
|
||||||
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
|
ins_pipe(iload_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Integer into a Long Register
|
||||||
|
instruct loadI2L(iRegL dst, memory mem) %{
|
||||||
|
match(Set dst (ConvI2L (LoadI mem)));
|
||||||
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "LDSW $mem,$dst\t! int -> long" %}
|
||||||
|
opcode(Assembler::ldsw_op3);
|
||||||
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
|
ins_pipe(iload_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Integer into a Long Register
|
||||||
|
instruct loadUI2L(iRegL dst, memory mem) %{
|
||||||
|
match(Set dst (LoadUI2L mem));
|
||||||
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "LDUW $mem,$dst\t! uint -> long" %}
|
||||||
opcode(Assembler::lduw_op3);
|
opcode(Assembler::lduw_op3);
|
||||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
|
@ -5356,6 +5416,7 @@ instruct loadI(iRegI dst, memory mem) %{
|
||||||
instruct loadL(iRegL dst, memory mem ) %{
|
instruct loadL(iRegL dst, memory mem ) %{
|
||||||
match(Set dst (LoadL mem));
|
match(Set dst (LoadL mem));
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
size(4);
|
size(4);
|
||||||
format %{ "LDX $mem,$dst\t! long" %}
|
format %{ "LDX $mem,$dst\t! long" %}
|
||||||
opcode(Assembler::ldx_op3);
|
opcode(Assembler::ldx_op3);
|
||||||
|
@ -5471,13 +5532,11 @@ instruct loadN(iRegN dst, memory mem) %{
|
||||||
|
|
||||||
format %{ "LDUW $mem,$dst\t! compressed ptr" %}
|
format %{ "LDUW $mem,$dst\t! compressed ptr" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
Register base = as_Register($mem$$base);
|
Register index = $mem$$index$$Register;
|
||||||
Register index = as_Register($mem$$index);
|
|
||||||
Register dst = $dst$$Register;
|
|
||||||
if (index != G0) {
|
if (index != G0) {
|
||||||
__ lduw(base, index, dst);
|
__ lduw($mem$$base$$Register, index, $dst$$Register);
|
||||||
} else {
|
} else {
|
||||||
__ lduw(base, $mem$$disp, dst);
|
__ lduw($mem$$base$$Register, $mem$$disp, $dst$$Register);
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
|
@ -5521,18 +5580,6 @@ instruct loadNKlass(iRegN dst, memory mem) %{
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Short (16bit signed)
|
|
||||||
instruct loadS(iRegI dst, memory mem) %{
|
|
||||||
match(Set dst (LoadS mem));
|
|
||||||
ins_cost(MEMORY_REF_COST);
|
|
||||||
|
|
||||||
size(4);
|
|
||||||
format %{ "LDSH $mem,$dst" %}
|
|
||||||
opcode(Assembler::ldsh_op3);
|
|
||||||
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
|
||||||
ins_pipe(iload_mask_mem);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Load Double
|
// Load Double
|
||||||
instruct loadD(regD dst, memory mem) %{
|
instruct loadD(regD dst, memory mem) %{
|
||||||
match(Set dst (LoadD mem));
|
match(Set dst (LoadD mem));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -129,13 +129,19 @@ Address::Address(address loc, RelocationHolder spec) {
|
||||||
// Convert the raw encoding form into the form expected by the constructor for
|
// Convert the raw encoding form into the form expected by the constructor for
|
||||||
// Address. An index of 4 (rsp) corresponds to having no index, so convert
|
// Address. An index of 4 (rsp) corresponds to having no index, so convert
|
||||||
// that to noreg for the Address constructor.
|
// that to noreg for the Address constructor.
|
||||||
Address Address::make_raw(int base, int index, int scale, int disp) {
|
Address Address::make_raw(int base, int index, int scale, int disp, bool disp_is_oop) {
|
||||||
|
RelocationHolder rspec;
|
||||||
|
if (disp_is_oop) {
|
||||||
|
rspec = Relocation::spec_simple(relocInfo::oop_type);
|
||||||
|
}
|
||||||
bool valid_index = index != rsp->encoding();
|
bool valid_index = index != rsp->encoding();
|
||||||
if (valid_index) {
|
if (valid_index) {
|
||||||
Address madr(as_Register(base), as_Register(index), (Address::ScaleFactor)scale, in_ByteSize(disp));
|
Address madr(as_Register(base), as_Register(index), (Address::ScaleFactor)scale, in_ByteSize(disp));
|
||||||
|
madr._rspec = rspec;
|
||||||
return madr;
|
return madr;
|
||||||
} else {
|
} else {
|
||||||
Address madr(as_Register(base), noreg, Address::no_scale, in_ByteSize(disp));
|
Address madr(as_Register(base), noreg, Address::no_scale, in_ByteSize(disp));
|
||||||
|
madr._rspec = rspec;
|
||||||
return madr;
|
return madr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3892,6 +3898,21 @@ void Assembler::movq(Address dst, Register src) {
|
||||||
emit_operand(src, dst);
|
emit_operand(src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Assembler::movsbq(Register dst, Address src) {
|
||||||
|
InstructionMark im(this);
|
||||||
|
prefixq(src, dst);
|
||||||
|
emit_byte(0x0F);
|
||||||
|
emit_byte(0xBE);
|
||||||
|
emit_operand(dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::movsbq(Register dst, Register src) {
|
||||||
|
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||||
|
emit_byte(0x0F);
|
||||||
|
emit_byte(0xBE);
|
||||||
|
emit_byte(0xC0 | encode);
|
||||||
|
}
|
||||||
|
|
||||||
void Assembler::movslq(Register dst, int32_t imm32) {
|
void Assembler::movslq(Register dst, int32_t imm32) {
|
||||||
// dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx)
|
// dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx)
|
||||||
// and movslq(r8, 3); as movl $0x0000000048000000,(%rbx)
|
// and movslq(r8, 3); as movl $0x0000000048000000,(%rbx)
|
||||||
|
@ -3925,6 +3946,51 @@ void Assembler::movslq(Register dst, Register src) {
|
||||||
emit_byte(0xC0 | encode);
|
emit_byte(0xC0 | encode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Assembler::movswq(Register dst, Address src) {
|
||||||
|
InstructionMark im(this);
|
||||||
|
prefixq(src, dst);
|
||||||
|
emit_byte(0x0F);
|
||||||
|
emit_byte(0xBF);
|
||||||
|
emit_operand(dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::movswq(Register dst, Register src) {
|
||||||
|
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||||
|
emit_byte(0x0F);
|
||||||
|
emit_byte(0xBF);
|
||||||
|
emit_byte(0xC0 | encode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::movzbq(Register dst, Address src) {
|
||||||
|
InstructionMark im(this);
|
||||||
|
prefixq(src, dst);
|
||||||
|
emit_byte(0x0F);
|
||||||
|
emit_byte(0xB6);
|
||||||
|
emit_operand(dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::movzbq(Register dst, Register src) {
|
||||||
|
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||||
|
emit_byte(0x0F);
|
||||||
|
emit_byte(0xB6);
|
||||||
|
emit_byte(0xC0 | encode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::movzwq(Register dst, Address src) {
|
||||||
|
InstructionMark im(this);
|
||||||
|
prefixq(src, dst);
|
||||||
|
emit_byte(0x0F);
|
||||||
|
emit_byte(0xB7);
|
||||||
|
emit_operand(dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::movzwq(Register dst, Register src) {
|
||||||
|
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||||
|
emit_byte(0x0F);
|
||||||
|
emit_byte(0xB7);
|
||||||
|
emit_byte(0xC0 | encode);
|
||||||
|
}
|
||||||
|
|
||||||
void Assembler::negq(Register dst) {
|
void Assembler::negq(Register dst) {
|
||||||
int encode = prefixq_and_encode(dst->encoding());
|
int encode = prefixq_and_encode(dst->encoding());
|
||||||
emit_byte(0xF7);
|
emit_byte(0xF7);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -278,7 +278,7 @@ class Address VALUE_OBJ_CLASS_SPEC {
|
||||||
// Convert the raw encoding form into the form expected by the constructor for
|
// Convert the raw encoding form into the form expected by the constructor for
|
||||||
// Address. An index of 4 (rsp) corresponds to having no index, so convert
|
// Address. An index of 4 (rsp) corresponds to having no index, so convert
|
||||||
// that to noreg for the Address constructor.
|
// that to noreg for the Address constructor.
|
||||||
static Address make_raw(int base, int index, int scale, int disp);
|
static Address make_raw(int base, int index, int scale, int disp, bool disp_is_oop);
|
||||||
|
|
||||||
static Address make_array(ArrayAddress);
|
static Address make_array(ArrayAddress);
|
||||||
|
|
||||||
|
@ -1138,6 +1138,9 @@ private:
|
||||||
void movsbl(Register dst, Register src);
|
void movsbl(Register dst, Register src);
|
||||||
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
|
void movsbq(Register dst, Address src);
|
||||||
|
void movsbq(Register dst, Register src);
|
||||||
|
|
||||||
// Move signed 32bit immediate to 64bit extending sign
|
// Move signed 32bit immediate to 64bit extending sign
|
||||||
void movslq(Address dst, int32_t imm64);
|
void movslq(Address dst, int32_t imm64);
|
||||||
void movslq(Register dst, int32_t imm64);
|
void movslq(Register dst, int32_t imm64);
|
||||||
|
@ -1150,6 +1153,11 @@ private:
|
||||||
void movswl(Register dst, Address src);
|
void movswl(Register dst, Address src);
|
||||||
void movswl(Register dst, Register src);
|
void movswl(Register dst, Register src);
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
void movswq(Register dst, Address src);
|
||||||
|
void movswq(Register dst, Register src);
|
||||||
|
#endif
|
||||||
|
|
||||||
void movw(Address dst, int imm16);
|
void movw(Address dst, int imm16);
|
||||||
void movw(Register dst, Address src);
|
void movw(Register dst, Address src);
|
||||||
void movw(Address dst, Register src);
|
void movw(Address dst, Register src);
|
||||||
|
@ -1157,9 +1165,19 @@ private:
|
||||||
void movzbl(Register dst, Address src);
|
void movzbl(Register dst, Address src);
|
||||||
void movzbl(Register dst, Register src);
|
void movzbl(Register dst, Register src);
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
void movzbq(Register dst, Address src);
|
||||||
|
void movzbq(Register dst, Register src);
|
||||||
|
#endif
|
||||||
|
|
||||||
void movzwl(Register dst, Address src);
|
void movzwl(Register dst, Address src);
|
||||||
void movzwl(Register dst, Register src);
|
void movzwl(Register dst, Register src);
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
void movzwq(Register dst, Address src);
|
||||||
|
void movzwq(Register dst, Register src);
|
||||||
|
#endif
|
||||||
|
|
||||||
void mull(Address src);
|
void mull(Address src);
|
||||||
void mull(Register src);
|
void mull(Register src);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
// Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -3126,14 +3126,12 @@ encode %{
|
||||||
|
|
||||||
enc_class movq_ld(regXD dst, memory mem) %{
|
enc_class movq_ld(regXD dst, memory mem) %{
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
|
__ movq($dst$$XMMRegister, $mem$$Address);
|
||||||
__ movq(as_XMMRegister($dst$$reg), madr);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class movq_st(memory mem, regXD src) %{
|
enc_class movq_st(memory mem, regXD src) %{
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
|
__ movq($mem$$Address, $src$$XMMRegister);
|
||||||
__ movq(madr, as_XMMRegister($src$$reg));
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class pshufd_8x8(regX dst, regX src) %{
|
enc_class pshufd_8x8(regX dst, regX src) %{
|
||||||
|
@ -6396,20 +6394,93 @@ instruct loadB(xRegI dst, memory mem) %{
|
||||||
match(Set dst (LoadB mem));
|
match(Set dst (LoadB mem));
|
||||||
|
|
||||||
ins_cost(125);
|
ins_cost(125);
|
||||||
format %{ "MOVSX8 $dst,$mem" %}
|
format %{ "MOVSX8 $dst,$mem\t# byte" %}
|
||||||
opcode(0xBE, 0x0F);
|
|
||||||
ins_encode( OpcS, OpcP, RegMem(dst,mem));
|
ins_encode %{
|
||||||
|
__ movsbl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Byte (8bit UNsigned)
|
// Load Byte (8bit signed) into Long Register
|
||||||
instruct loadUB(xRegI dst, memory mem, immI_255 bytemask) %{
|
instruct loadB2L(eRegL dst, memory mem) %{
|
||||||
match(Set dst (AndI (LoadB mem) bytemask));
|
match(Set dst (ConvI2L (LoadB mem)));
|
||||||
|
|
||||||
|
ins_cost(375);
|
||||||
|
format %{ "MOVSX8 $dst.lo,$mem\t# byte -> long\n\t"
|
||||||
|
"MOV $dst.hi,$dst.lo\n\t"
|
||||||
|
"SAR $dst.hi,7" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movsbl($dst$$Register, $mem$$Address);
|
||||||
|
__ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
|
||||||
|
__ sarl(HIGH_FROM_LOW($dst$$Register), 7); // 24+1 MSB are already signed extended.
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Byte (8bit UNsigned)
|
||||||
|
instruct loadUB(xRegI dst, memory mem) %{
|
||||||
|
match(Set dst (LoadUB mem));
|
||||||
|
|
||||||
ins_cost(125);
|
ins_cost(125);
|
||||||
format %{ "MOVZX8 $dst,$mem" %}
|
format %{ "MOVZX8 $dst,$mem\t# ubyte -> int" %}
|
||||||
opcode(0xB6, 0x0F);
|
|
||||||
ins_encode( OpcS, OpcP, RegMem(dst,mem));
|
ins_encode %{
|
||||||
|
__ movzbl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Byte (8 bit UNsigned) into Long Register
|
||||||
|
instruct loadUB2L(eRegL dst, memory mem)
|
||||||
|
%{
|
||||||
|
match(Set dst (ConvI2L (LoadUB mem)));
|
||||||
|
|
||||||
|
ins_cost(250);
|
||||||
|
format %{ "MOVZX8 $dst.lo,$mem\t# ubyte -> long\n\t"
|
||||||
|
"XOR $dst.hi,$dst.hi" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movzbl($dst$$Register, $mem$$Address);
|
||||||
|
__ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Short (16bit signed)
|
||||||
|
instruct loadS(eRegI dst, memory mem) %{
|
||||||
|
match(Set dst (LoadS mem));
|
||||||
|
|
||||||
|
ins_cost(125);
|
||||||
|
format %{ "MOVSX $dst,$mem\t# short" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movswl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Short (16bit signed) into Long Register
|
||||||
|
instruct loadS2L(eRegL dst, memory mem) %{
|
||||||
|
match(Set dst (ConvI2L (LoadS mem)));
|
||||||
|
|
||||||
|
ins_cost(375);
|
||||||
|
format %{ "MOVSX $dst.lo,$mem\t# short -> long\n\t"
|
||||||
|
"MOV $dst.hi,$dst.lo\n\t"
|
||||||
|
"SAR $dst.hi,15" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movswl($dst$$Register, $mem$$Address);
|
||||||
|
__ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
|
||||||
|
__ sarl(HIGH_FROM_LOW($dst$$Register), 15); // 16+1 MSB are already signed extended.
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -6418,9 +6489,29 @@ instruct loadUS(eRegI dst, memory mem) %{
|
||||||
match(Set dst (LoadUS mem));
|
match(Set dst (LoadUS mem));
|
||||||
|
|
||||||
ins_cost(125);
|
ins_cost(125);
|
||||||
format %{ "MOVZX $dst,$mem" %}
|
format %{ "MOVZX $dst,$mem\t# ushort/char -> int" %}
|
||||||
opcode(0xB7, 0x0F);
|
|
||||||
ins_encode( OpcS, OpcP, RegMem(dst,mem));
|
ins_encode %{
|
||||||
|
__ movzwl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Short/Char (16 bit UNsigned) into Long Register
|
||||||
|
instruct loadUS2L(eRegL dst, memory mem)
|
||||||
|
%{
|
||||||
|
match(Set dst (ConvI2L (LoadUS mem)));
|
||||||
|
|
||||||
|
ins_cost(250);
|
||||||
|
format %{ "MOVZX $dst.lo,$mem\t# ushort/char -> long\n\t"
|
||||||
|
"XOR $dst.hi,$dst.hi" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movzwl($dst$$Register, $mem$$Address);
|
||||||
|
__ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -6429,9 +6520,46 @@ instruct loadI(eRegI dst, memory mem) %{
|
||||||
match(Set dst (LoadI mem));
|
match(Set dst (LoadI mem));
|
||||||
|
|
||||||
ins_cost(125);
|
ins_cost(125);
|
||||||
format %{ "MOV $dst,$mem" %}
|
format %{ "MOV $dst,$mem\t# int" %}
|
||||||
opcode(0x8B);
|
|
||||||
ins_encode( OpcP, RegMem(dst,mem));
|
ins_encode %{
|
||||||
|
__ movl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Integer into Long Register
|
||||||
|
instruct loadI2L(eRegL dst, memory mem) %{
|
||||||
|
match(Set dst (ConvI2L (LoadI mem)));
|
||||||
|
|
||||||
|
ins_cost(375);
|
||||||
|
format %{ "MOV $dst.lo,$mem\t# int -> long\n\t"
|
||||||
|
"MOV $dst.hi,$dst.lo\n\t"
|
||||||
|
"SAR $dst.hi,31" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movl($dst$$Register, $mem$$Address);
|
||||||
|
__ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
|
||||||
|
__ sarl(HIGH_FROM_LOW($dst$$Register), 31);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Integer into Long Register
|
||||||
|
instruct loadUI2L(eRegL dst, memory mem) %{
|
||||||
|
match(Set dst (LoadUI2L mem));
|
||||||
|
|
||||||
|
ins_cost(250);
|
||||||
|
format %{ "MOV $dst.lo,$mem\t# uint -> long\n\t"
|
||||||
|
"XOR $dst.hi,$dst.hi" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movl($dst$$Register, $mem$$Address);
|
||||||
|
__ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -6442,10 +6570,16 @@ instruct loadL(eRegL dst, load_long_memory mem) %{
|
||||||
match(Set dst (LoadL mem));
|
match(Set dst (LoadL mem));
|
||||||
|
|
||||||
ins_cost(250);
|
ins_cost(250);
|
||||||
format %{ "MOV $dst.lo,$mem\n\t"
|
format %{ "MOV $dst.lo,$mem\t# long\n\t"
|
||||||
"MOV $dst.hi,$mem+4" %}
|
"MOV $dst.hi,$mem+4" %}
|
||||||
opcode(0x8B, 0x8B);
|
|
||||||
ins_encode( OpcP, RegMem(dst,mem), OpcS, RegMem_Hi(dst,mem));
|
ins_encode %{
|
||||||
|
Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false);
|
||||||
|
Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false);
|
||||||
|
__ movl($dst$$Register, Amemlo);
|
||||||
|
__ movl(HIGH_FROM_LOW($dst$$Register), Amemhi);
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_long_mem);
|
ins_pipe(ialu_reg_long_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -6521,17 +6655,6 @@ instruct loadKlass(eRegP dst, memory mem) %{
|
||||||
ins_pipe( ialu_reg_mem );
|
ins_pipe( ialu_reg_mem );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Short (16bit signed)
|
|
||||||
instruct loadS(eRegI dst, memory mem) %{
|
|
||||||
match(Set dst (LoadS mem));
|
|
||||||
|
|
||||||
ins_cost(125);
|
|
||||||
format %{ "MOVSX $dst,$mem" %}
|
|
||||||
opcode(0xBF, 0x0F);
|
|
||||||
ins_encode( OpcS, OpcP, RegMem(dst,mem));
|
|
||||||
ins_pipe( ialu_reg_mem );
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Load Double
|
// Load Double
|
||||||
instruct loadD(regD dst, memory mem) %{
|
instruct loadD(regD dst, memory mem) %{
|
||||||
predicate(UseSSE<=1);
|
predicate(UseSSE<=1);
|
||||||
|
@ -7957,7 +8080,7 @@ instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlags
|
||||||
__ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
|
__ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
|
||||||
if( os::is_MP() )
|
if( os::is_MP() )
|
||||||
__ lock();
|
__ lock();
|
||||||
__ cmpxchg8(Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp));
|
__ cmpxchg8($mem$$Address);
|
||||||
__ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
|
__ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_cmpxchg );
|
ins_pipe( pipe_cmpxchg );
|
||||||
|
@ -11467,6 +11590,7 @@ instruct convI2X_reg(regX dst, eRegI src) %{
|
||||||
instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
|
instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
|
||||||
match(Set dst (ConvI2L src));
|
match(Set dst (ConvI2L src));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
ins_cost(375);
|
||||||
format %{ "MOV $dst.lo,$src\n\t"
|
format %{ "MOV $dst.lo,$src\n\t"
|
||||||
"MOV $dst.hi,$src\n\t"
|
"MOV $dst.hi,$src\n\t"
|
||||||
"SAR $dst.hi,31" %}
|
"SAR $dst.hi,31" %}
|
||||||
|
@ -11478,6 +11602,7 @@ instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
|
||||||
instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{
|
instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{
|
||||||
match(Set dst (AndL (ConvI2L src) mask) );
|
match(Set dst (AndL (ConvI2L src) mask) );
|
||||||
effect( KILL flags );
|
effect( KILL flags );
|
||||||
|
ins_cost(250);
|
||||||
format %{ "MOV $dst.lo,$src\n\t"
|
format %{ "MOV $dst.lo,$src\n\t"
|
||||||
"XOR $dst.hi,$dst.hi" %}
|
"XOR $dst.hi,$dst.hi" %}
|
||||||
opcode(0x33); // XOR
|
opcode(0x33); // XOR
|
||||||
|
@ -11489,6 +11614,7 @@ instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags
|
||||||
instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{
|
instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{
|
||||||
match(Set dst (AndL src mask) );
|
match(Set dst (AndL src mask) );
|
||||||
effect( KILL flags );
|
effect( KILL flags );
|
||||||
|
ins_cost(250);
|
||||||
format %{ "MOV $dst.lo,$src.lo\n\t"
|
format %{ "MOV $dst.lo,$src.lo\n\t"
|
||||||
"XOR $dst.hi,$dst.hi\n\t" %}
|
"XOR $dst.hi,$dst.hi\n\t" %}
|
||||||
opcode(0x33); // XOR
|
opcode(0x33); // XOR
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
// Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -3462,14 +3462,12 @@ encode %{
|
||||||
|
|
||||||
enc_class movq_ld(regD dst, memory mem) %{
|
enc_class movq_ld(regD dst, memory mem) %{
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
|
__ movq($dst$$XMMRegister, $mem$$Address);
|
||||||
__ movq(as_XMMRegister($dst$$reg), madr);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class movq_st(memory mem, regD src) %{
|
enc_class movq_st(memory mem, regD src) %{
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
|
__ movq($mem$$Address, $src$$XMMRegister);
|
||||||
__ movq(madr, as_XMMRegister($src$$reg));
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class pshufd_8x8(regF dst, regF src) %{
|
enc_class pshufd_8x8(regF dst, regF src) %{
|
||||||
|
@ -6031,70 +6029,88 @@ instruct loadB(rRegI dst, memory mem)
|
||||||
|
|
||||||
ins_cost(125);
|
ins_cost(125);
|
||||||
format %{ "movsbl $dst, $mem\t# byte" %}
|
format %{ "movsbl $dst, $mem\t# byte" %}
|
||||||
opcode(0x0F, 0xBE);
|
|
||||||
ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
|
__ movsbl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Byte (8 bit signed) into long
|
// Load Byte (8 bit signed) into Long Register
|
||||||
// instruct loadB2L(rRegL dst, memory mem)
|
instruct loadB2L(rRegL dst, memory mem)
|
||||||
// %{
|
|
||||||
// match(Set dst (ConvI2L (LoadB mem)));
|
|
||||||
|
|
||||||
// ins_cost(125);
|
|
||||||
// format %{ "movsbq $dst, $mem\t# byte -> long" %}
|
|
||||||
// opcode(0x0F, 0xBE);
|
|
||||||
// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
|
|
||||||
// ins_pipe(ialu_reg_mem);
|
|
||||||
// %}
|
|
||||||
|
|
||||||
// Load Byte (8 bit UNsigned)
|
|
||||||
instruct loadUB(rRegI dst, memory mem, immI_255 bytemask)
|
|
||||||
%{
|
%{
|
||||||
match(Set dst (AndI (LoadB mem) bytemask));
|
match(Set dst (ConvI2L (LoadB mem)));
|
||||||
|
|
||||||
|
ins_cost(125);
|
||||||
|
format %{ "movsbq $dst, $mem\t# byte -> long" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movsbq($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Byte (8 bit UNsigned)
|
||||||
|
instruct loadUB(rRegI dst, memory mem)
|
||||||
|
%{
|
||||||
|
match(Set dst (LoadUB mem));
|
||||||
|
|
||||||
ins_cost(125);
|
ins_cost(125);
|
||||||
format %{ "movzbl $dst, $mem\t# ubyte" %}
|
format %{ "movzbl $dst, $mem\t# ubyte" %}
|
||||||
opcode(0x0F, 0xB6);
|
|
||||||
ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
|
__ movzbl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Byte (8 bit UNsigned) into long
|
// Load Unsigned Byte (8 bit UNsigned) into Long Register
|
||||||
// instruct loadUB2L(rRegL dst, memory mem, immI_255 bytemask)
|
instruct loadUB2L(rRegL dst, memory mem)
|
||||||
// %{
|
%{
|
||||||
// match(Set dst (ConvI2L (AndI (LoadB mem) bytemask)));
|
match(Set dst (ConvI2L (LoadUB mem)));
|
||||||
|
|
||||||
// ins_cost(125);
|
ins_cost(125);
|
||||||
// format %{ "movzbl $dst, $mem\t# ubyte -> long" %}
|
format %{ "movzbq $dst, $mem\t# ubyte -> long" %}
|
||||||
// opcode(0x0F, 0xB6);
|
|
||||||
// ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
// ins_pipe(ialu_reg_mem);
|
__ movzbq($dst$$Register, $mem$$Address);
|
||||||
// %}
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
// Load Short (16 bit signed)
|
// Load Short (16 bit signed)
|
||||||
instruct loadS(rRegI dst, memory mem)
|
instruct loadS(rRegI dst, memory mem)
|
||||||
%{
|
%{
|
||||||
match(Set dst (LoadS mem));
|
match(Set dst (LoadS mem));
|
||||||
|
|
||||||
ins_cost(125); // XXX
|
ins_cost(125);
|
||||||
format %{ "movswl $dst, $mem\t# short" %}
|
format %{ "movswl $dst, $mem\t# short" %}
|
||||||
opcode(0x0F, 0xBF);
|
|
||||||
ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
|
__ movswl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Short (16 bit signed) into long
|
// Load Short (16 bit signed) into Long Register
|
||||||
// instruct loadS2L(rRegL dst, memory mem)
|
instruct loadS2L(rRegL dst, memory mem)
|
||||||
// %{
|
%{
|
||||||
// match(Set dst (ConvI2L (LoadS mem)));
|
match(Set dst (ConvI2L (LoadS mem)));
|
||||||
|
|
||||||
// ins_cost(125); // XXX
|
ins_cost(125);
|
||||||
// format %{ "movswq $dst, $mem\t# short -> long" %}
|
format %{ "movswq $dst, $mem\t# short -> long" %}
|
||||||
// opcode(0x0F, 0xBF);
|
|
||||||
// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
// ins_pipe(ialu_reg_mem);
|
__ movswq($dst$$Register, $mem$$Address);
|
||||||
// %}
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
// Load Unsigned Short/Char (16 bit UNsigned)
|
// Load Unsigned Short/Char (16 bit UNsigned)
|
||||||
instruct loadUS(rRegI dst, memory mem)
|
instruct loadUS(rRegI dst, memory mem)
|
||||||
|
@ -6103,32 +6119,71 @@ instruct loadUS(rRegI dst, memory mem)
|
||||||
|
|
||||||
ins_cost(125);
|
ins_cost(125);
|
||||||
format %{ "movzwl $dst, $mem\t# ushort/char" %}
|
format %{ "movzwl $dst, $mem\t# ushort/char" %}
|
||||||
opcode(0x0F, 0xB7);
|
|
||||||
ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
|
__ movzwl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Unsigned Short/Char (16 bit UNsigned) into long
|
// Load Unsigned Short/Char (16 bit UNsigned) into Long Register
|
||||||
// instruct loadUS2L(rRegL dst, memory mem)
|
instruct loadUS2L(rRegL dst, memory mem)
|
||||||
// %{
|
%{
|
||||||
// match(Set dst (ConvI2L (LoadUS mem)));
|
match(Set dst (ConvI2L (LoadUS mem)));
|
||||||
|
|
||||||
// ins_cost(125);
|
ins_cost(125);
|
||||||
// format %{ "movzwl $dst, $mem\t# ushort/char -> long" %}
|
format %{ "movzwq $dst, $mem\t# ushort/char -> long" %}
|
||||||
// opcode(0x0F, 0xB7);
|
|
||||||
// ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
// ins_pipe(ialu_reg_mem);
|
__ movzwq($dst$$Register, $mem$$Address);
|
||||||
// %}
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
// Load Integer
|
// Load Integer
|
||||||
instruct loadI(rRegI dst, memory mem)
|
instruct loadI(rRegI dst, memory mem)
|
||||||
%{
|
%{
|
||||||
match(Set dst (LoadI mem));
|
match(Set dst (LoadI mem));
|
||||||
|
|
||||||
ins_cost(125); // XXX
|
ins_cost(125);
|
||||||
format %{ "movl $dst, $mem\t# int" %}
|
format %{ "movl $dst, $mem\t# int" %}
|
||||||
opcode(0x8B);
|
|
||||||
ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
|
__ movl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Integer into Long Register
|
||||||
|
instruct loadI2L(rRegL dst, memory mem)
|
||||||
|
%{
|
||||||
|
match(Set dst (ConvI2L (LoadI mem)));
|
||||||
|
|
||||||
|
ins_cost(125);
|
||||||
|
format %{ "movslq $dst, $mem\t# int -> long" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movslq($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Load Unsigned Integer into Long Register
|
||||||
|
instruct loadUI2L(rRegL dst, memory mem)
|
||||||
|
%{
|
||||||
|
match(Set dst (LoadUI2L mem));
|
||||||
|
|
||||||
|
ins_cost(125);
|
||||||
|
format %{ "movl $dst, $mem\t# uint -> long" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ movl($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem);
|
ins_pipe(ialu_reg_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -6137,10 +6192,13 @@ instruct loadL(rRegL dst, memory mem)
|
||||||
%{
|
%{
|
||||||
match(Set dst (LoadL mem));
|
match(Set dst (LoadL mem));
|
||||||
|
|
||||||
ins_cost(125); // XXX
|
ins_cost(125);
|
||||||
format %{ "movq $dst, $mem\t# long" %}
|
format %{ "movq $dst, $mem\t# long" %}
|
||||||
opcode(0x8B);
|
|
||||||
ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
|
ins_encode %{
|
||||||
|
__ movq($dst$$Register, $mem$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
ins_pipe(ialu_reg_mem); // XXX
|
ins_pipe(ialu_reg_mem); // XXX
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -10804,16 +10862,6 @@ instruct convI2L_reg_reg(rRegL dst, rRegI src)
|
||||||
// ins_pipe(ialu_reg_reg);
|
// ins_pipe(ialu_reg_reg);
|
||||||
// %}
|
// %}
|
||||||
|
|
||||||
instruct convI2L_reg_mem(rRegL dst, memory src)
|
|
||||||
%{
|
|
||||||
match(Set dst (ConvI2L (LoadI src)));
|
|
||||||
|
|
||||||
format %{ "movslq $dst, $src\t# i2l" %}
|
|
||||||
opcode(0x63); // needs REX.W
|
|
||||||
ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst,src));
|
|
||||||
ins_pipe(ialu_reg_mem);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Zero-extend convert int to long
|
// Zero-extend convert int to long
|
||||||
instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
|
instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
|
||||||
%{
|
%{
|
||||||
|
|
|
@ -70,6 +70,7 @@ const char *NameList::iter() {
|
||||||
else return (_iter <_cur-1 ? _names[++_iter] : NULL);
|
else return (_iter <_cur-1 ? _names[++_iter] : NULL);
|
||||||
}
|
}
|
||||||
const char *NameList::current() { return (_iter < _cur ? _names[_iter] : NULL); }
|
const char *NameList::current() { return (_iter < _cur ? _names[_iter] : NULL); }
|
||||||
|
const char *NameList::peek(int skip) { return (_iter + skip < _cur ? _names[_iter + skip] : NULL); }
|
||||||
|
|
||||||
// Return 'true' if current entry is signal
|
// Return 'true' if current entry is signal
|
||||||
bool NameList::current_is_signal() {
|
bool NameList::current_is_signal() {
|
||||||
|
@ -248,11 +249,13 @@ Form::DataType Form::ideal_to_Reg_type(const char *name) const {
|
||||||
// True if 'opType', an ideal name, loads or stores.
|
// True if 'opType', an ideal name, loads or stores.
|
||||||
Form::DataType Form::is_load_from_memory(const char *opType) const {
|
Form::DataType Form::is_load_from_memory(const char *opType) const {
|
||||||
if( strcmp(opType,"LoadB")==0 ) return Form::idealB;
|
if( strcmp(opType,"LoadB")==0 ) return Form::idealB;
|
||||||
|
if( strcmp(opType,"LoadUB")==0 ) return Form::idealB;
|
||||||
if( strcmp(opType,"LoadUS")==0 ) return Form::idealC;
|
if( strcmp(opType,"LoadUS")==0 ) return Form::idealC;
|
||||||
if( strcmp(opType,"LoadD")==0 ) return Form::idealD;
|
if( strcmp(opType,"LoadD")==0 ) return Form::idealD;
|
||||||
if( strcmp(opType,"LoadD_unaligned")==0 ) return Form::idealD;
|
if( strcmp(opType,"LoadD_unaligned")==0 ) return Form::idealD;
|
||||||
if( strcmp(opType,"LoadF")==0 ) return Form::idealF;
|
if( strcmp(opType,"LoadF")==0 ) return Form::idealF;
|
||||||
if( strcmp(opType,"LoadI")==0 ) return Form::idealI;
|
if( strcmp(opType,"LoadI")==0 ) return Form::idealI;
|
||||||
|
if( strcmp(opType,"LoadUI2L")==0 ) return Form::idealI;
|
||||||
if( strcmp(opType,"LoadKlass")==0 ) return Form::idealP;
|
if( strcmp(opType,"LoadKlass")==0 ) return Form::idealP;
|
||||||
if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealN;
|
if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealN;
|
||||||
if( strcmp(opType,"LoadL")==0 ) return Form::idealL;
|
if( strcmp(opType,"LoadL")==0 ) return Form::idealL;
|
||||||
|
|
|
@ -342,6 +342,7 @@ public:
|
||||||
void reset(); // Reset iteration
|
void reset(); // Reset iteration
|
||||||
const char *iter(); // after reset(), first element : else next
|
const char *iter(); // after reset(), first element : else next
|
||||||
const char *current(); // return current element in iteration.
|
const char *current(); // return current element in iteration.
|
||||||
|
const char *peek(int skip = 1); // returns element + skip in iteration if there is one
|
||||||
|
|
||||||
bool current_is_signal(); // Return 'true' if current entry is signal
|
bool current_is_signal(); // Return 'true' if current entry is signal
|
||||||
bool is_signal(const char *entry); // Return true if entry is a signal
|
bool is_signal(const char *entry); // Return true if entry is a signal
|
||||||
|
|
|
@ -3310,8 +3310,8 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
|
||||||
static const char *needs_ideal_memory_list[] = {
|
static const char *needs_ideal_memory_list[] = {
|
||||||
"StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
|
"StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
|
||||||
"StoreB","StoreC","Store" ,"StoreFP",
|
"StoreB","StoreC","Store" ,"StoreFP",
|
||||||
"LoadI" ,"LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" ,
|
"LoadI", "LoadUI2L", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" ,
|
||||||
"LoadB" ,"LoadUS" ,"LoadS" ,"Load" ,
|
"LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,
|
||||||
"Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
|
"Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
|
||||||
"Store8B","Store4B","Store8C","Store4C","Store2C",
|
"Store8B","Store4B","Store8C","Store4C","Store2C",
|
||||||
"Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
|
"Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
|
||||||
|
@ -3431,10 +3431,16 @@ int MatchNode::cisc_spill_match(FormDict& globals, RegisterForm* registers, Matc
|
||||||
const InstructForm *form2_inst = form2 ? form2->is_instruction() : NULL;
|
const InstructForm *form2_inst = form2 ? form2->is_instruction() : NULL;
|
||||||
const char *name_left = mRule2->_lChild ? mRule2->_lChild->_opType : NULL;
|
const char *name_left = mRule2->_lChild ? mRule2->_lChild->_opType : NULL;
|
||||||
const char *name_right = mRule2->_rChild ? mRule2->_rChild->_opType : NULL;
|
const char *name_right = mRule2->_rChild ? mRule2->_rChild->_opType : NULL;
|
||||||
|
DataType data_type = Form::none;
|
||||||
|
if (form->is_operand()) {
|
||||||
|
// Make sure the loadX matches the type of the reg
|
||||||
|
data_type = form->ideal_to_Reg_type(form->is_operand()->ideal_type(globals));
|
||||||
|
}
|
||||||
// Detect reg vs (loadX memory)
|
// Detect reg vs (loadX memory)
|
||||||
if( form->is_cisc_reg(globals)
|
if( form->is_cisc_reg(globals)
|
||||||
&& form2_inst
|
&& form2_inst
|
||||||
&& (is_load_from_memory(mRule2->_opType) != Form::none) // reg vs. (load memory)
|
&& data_type != Form::none
|
||||||
|
&& (is_load_from_memory(mRule2->_opType) == data_type) // reg vs. (load memory)
|
||||||
&& (name_left != NULL) // NOT (load)
|
&& (name_left != NULL) // NOT (load)
|
||||||
&& (name_right == NULL) ) { // NOT (load memory foo)
|
&& (name_right == NULL) ) { // NOT (load memory foo)
|
||||||
const Form *form2_left = name_left ? globals[name_left] : NULL;
|
const Form *form2_left = name_left ? globals[name_left] : NULL;
|
||||||
|
|
|
@ -2139,8 +2139,59 @@ public:
|
||||||
// A subfield variable, '$$' prefix
|
// A subfield variable, '$$' prefix
|
||||||
emit_field( rep_var );
|
emit_field( rep_var );
|
||||||
} else {
|
} else {
|
||||||
// A replacement variable, '$' prefix
|
if (_strings_to_emit.peek() != NULL &&
|
||||||
|
strcmp(_strings_to_emit.peek(), "$Address") == 0) {
|
||||||
|
fprintf(_fp, "Address::make_raw(");
|
||||||
|
|
||||||
emit_rep_var( rep_var );
|
emit_rep_var( rep_var );
|
||||||
|
fprintf(_fp,"->base(ra_,this,idx%d), ", _operand_idx);
|
||||||
|
|
||||||
|
_reg_status = LITERAL_ACCESSED;
|
||||||
|
emit_rep_var( rep_var );
|
||||||
|
fprintf(_fp,"->index(ra_,this,idx%d), ", _operand_idx);
|
||||||
|
|
||||||
|
_reg_status = LITERAL_ACCESSED;
|
||||||
|
emit_rep_var( rep_var );
|
||||||
|
fprintf(_fp,"->scale(), ");
|
||||||
|
|
||||||
|
_reg_status = LITERAL_ACCESSED;
|
||||||
|
emit_rep_var( rep_var );
|
||||||
|
Form::DataType stack_type = _operand ? _operand->is_user_name_for_sReg() : Form::none;
|
||||||
|
if( _operand && _operand_idx==0 && stack_type != Form::none ) {
|
||||||
|
fprintf(_fp,"->disp(ra_,this,0), ");
|
||||||
|
} else {
|
||||||
|
fprintf(_fp,"->disp(ra_,this,idx%d), ", _operand_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
_reg_status = LITERAL_ACCESSED;
|
||||||
|
emit_rep_var( rep_var );
|
||||||
|
fprintf(_fp,"->disp_is_oop())");
|
||||||
|
|
||||||
|
// skip trailing $Address
|
||||||
|
_strings_to_emit.iter();
|
||||||
|
} else {
|
||||||
|
// A replacement variable, '$' prefix
|
||||||
|
const char* next = _strings_to_emit.peek();
|
||||||
|
const char* next2 = _strings_to_emit.peek(2);
|
||||||
|
if (next != NULL && next2 != NULL && strcmp(next2, "$Register") == 0 &&
|
||||||
|
(strcmp(next, "$base") == 0 || strcmp(next, "$index") == 0)) {
|
||||||
|
// handle $rev_var$$base$$Register and $rev_var$$index$$Register by
|
||||||
|
// producing as_Register(opnd_array(#)->base(ra_,this,idx1)).
|
||||||
|
fprintf(_fp, "as_Register(");
|
||||||
|
// emit the operand reference
|
||||||
|
emit_rep_var( rep_var );
|
||||||
|
rep_var = _strings_to_emit.iter();
|
||||||
|
assert(strcmp(rep_var, "$base") == 0 || strcmp(rep_var, "$index") == 0, "bad pattern");
|
||||||
|
// handle base or index
|
||||||
|
emit_field(rep_var);
|
||||||
|
rep_var = _strings_to_emit.iter();
|
||||||
|
assert(strcmp(rep_var, "$Register") == 0, "bad pattern");
|
||||||
|
// close up the parens
|
||||||
|
fprintf(_fp, ")");
|
||||||
|
} else {
|
||||||
|
emit_rep_var( rep_var );
|
||||||
|
}
|
||||||
|
}
|
||||||
} // end replacement and/or subfield
|
} // end replacement and/or subfield
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -129,11 +129,13 @@ macro(JumpProj)
|
||||||
macro(LShiftI)
|
macro(LShiftI)
|
||||||
macro(LShiftL)
|
macro(LShiftL)
|
||||||
macro(LoadB)
|
macro(LoadB)
|
||||||
|
macro(LoadUB)
|
||||||
macro(LoadUS)
|
macro(LoadUS)
|
||||||
macro(LoadD)
|
macro(LoadD)
|
||||||
macro(LoadD_unaligned)
|
macro(LoadD_unaligned)
|
||||||
macro(LoadF)
|
macro(LoadF)
|
||||||
macro(LoadI)
|
macro(LoadI)
|
||||||
|
macro(LoadUI2L)
|
||||||
macro(LoadKlass)
|
macro(LoadKlass)
|
||||||
macro(LoadNKlass)
|
macro(LoadNKlass)
|
||||||
macro(LoadL)
|
macro(LoadL)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2005,8 +2005,10 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
|
||||||
case Op_StoreP:
|
case Op_StoreP:
|
||||||
case Op_StoreN:
|
case Op_StoreN:
|
||||||
case Op_LoadB:
|
case Op_LoadB:
|
||||||
|
case Op_LoadUB:
|
||||||
case Op_LoadUS:
|
case Op_LoadUS:
|
||||||
case Op_LoadI:
|
case Op_LoadI:
|
||||||
|
case Op_LoadUI2L:
|
||||||
case Op_LoadKlass:
|
case Op_LoadKlass:
|
||||||
case Op_LoadNKlass:
|
case Op_LoadNKlass:
|
||||||
case Op_LoadL:
|
case Op_LoadL:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -778,7 +778,7 @@ Node *LoadNode::make( PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const Type
|
||||||
adr_type->offset() == arrayOopDesc::length_offset_in_bytes()),
|
adr_type->offset() == arrayOopDesc::length_offset_in_bytes()),
|
||||||
"use LoadRangeNode instead");
|
"use LoadRangeNode instead");
|
||||||
switch (bt) {
|
switch (bt) {
|
||||||
case T_BOOLEAN:
|
case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() );
|
||||||
case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() );
|
case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() );
|
||||||
case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() );
|
case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() );
|
||||||
case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() );
|
case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() );
|
||||||
|
@ -1616,6 +1616,22 @@ Node *LoadBNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
return LoadNode::Ideal(phase, can_reshape);
|
return LoadNode::Ideal(phase, can_reshape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------LoadUBNode::Ideal-------------------------------------
|
||||||
|
//
|
||||||
|
// If the previous store is to the same address as this load,
|
||||||
|
// and the value stored was larger than a byte, replace this load
|
||||||
|
// with the value stored truncated to a byte. If no truncation is
|
||||||
|
// needed, the replacement is done in LoadNode::Identity().
|
||||||
|
//
|
||||||
|
Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
|
Node* mem = in(MemNode::Memory);
|
||||||
|
Node* value = can_see_stored_value(mem, phase);
|
||||||
|
if (value && !phase->type(value)->higher_equal(_type))
|
||||||
|
return new (phase->C, 3) AndINode(value, phase->intcon(0xFF));
|
||||||
|
// Identity call will handle the case where truncation is not needed.
|
||||||
|
return LoadNode::Ideal(phase, can_reshape);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------LoadUSNode::Ideal-------------------------------------
|
//--------------------------LoadUSNode::Ideal-------------------------------------
|
||||||
//
|
//
|
||||||
// If the previous store is to the same address as this load,
|
// If the previous store is to the same address as this load,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -207,6 +207,19 @@ public:
|
||||||
virtual BasicType memory_type() const { return T_BYTE; }
|
virtual BasicType memory_type() const { return T_BYTE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//------------------------------LoadUBNode-------------------------------------
|
||||||
|
// Load a unsigned byte (8bits unsigned) from memory
|
||||||
|
class LoadUBNode : public LoadNode {
|
||||||
|
public:
|
||||||
|
LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti = TypeInt::UBYTE )
|
||||||
|
: LoadNode(c, mem, adr, at, ti) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual uint ideal_reg() const { return Op_RegI; }
|
||||||
|
virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
|
||||||
|
virtual int store_Opcode() const { return Op_StoreB; }
|
||||||
|
virtual BasicType memory_type() const { return T_BYTE; }
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------LoadUSNode-------------------------------------
|
//------------------------------LoadUSNode-------------------------------------
|
||||||
// Load an unsigned short/char (16bits unsigned) from memory
|
// Load an unsigned short/char (16bits unsigned) from memory
|
||||||
class LoadUSNode : public LoadNode {
|
class LoadUSNode : public LoadNode {
|
||||||
|
@ -232,6 +245,18 @@ public:
|
||||||
virtual BasicType memory_type() const { return T_INT; }
|
virtual BasicType memory_type() const { return T_INT; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//------------------------------LoadUI2LNode-----------------------------------
|
||||||
|
// Load an unsigned integer into long from memory
|
||||||
|
class LoadUI2LNode : public LoadNode {
|
||||||
|
public:
|
||||||
|
LoadUI2LNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeLong* t = TypeLong::UINT)
|
||||||
|
: LoadNode(c, mem, adr, at, t) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual uint ideal_reg() const { return Op_RegL; }
|
||||||
|
virtual int store_Opcode() const { return Op_StoreL; }
|
||||||
|
virtual BasicType memory_type() const { return T_LONG; }
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------LoadRangeNode----------------------------------
|
//------------------------------LoadRangeNode----------------------------------
|
||||||
// Load an array length from the array
|
// Load an array length from the array
|
||||||
class LoadRangeNode : public LoadINode {
|
class LoadRangeNode : public LoadINode {
|
||||||
|
|
|
@ -486,20 +486,23 @@ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF));
|
return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Masking sign bits off of a Byte? Let the matcher use an unsigned load
|
// Masking sign bits off of a Byte? Do an unsigned byte load.
|
||||||
if( lop == Op_LoadB &&
|
if (lop == Op_LoadB && mask == 0x000000FF) {
|
||||||
(!in(0) && load->in(0)) &&
|
return new (phase->C, 3) LoadUBNode(load->in(MemNode::Control),
|
||||||
(mask == 0x000000FF) ) {
|
load->in(MemNode::Memory),
|
||||||
// Associate this node with the LoadB, so the matcher can see them together.
|
load->in(MemNode::Address),
|
||||||
// If we don't do this, it is common for the LoadB to have one control
|
load->adr_type());
|
||||||
// edge, and the store or call containing this AndI to have a different
|
}
|
||||||
// control edge. This will cause Label_Root to group the AndI with
|
|
||||||
// the encoding store or call, so the matcher has no chance to match
|
// Masking sign bits off of a Byte plus additional lower bits? Do
|
||||||
// this AndI together with the LoadB. Setting the control edge here
|
// an unsigned byte load plus an and.
|
||||||
// prevents Label_Root from grouping the AndI with the store or call,
|
if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
|
||||||
// if it has a control edge that is inconsistent with the LoadB.
|
Node* ldub = new (phase->C, 3) LoadUBNode(load->in(MemNode::Control),
|
||||||
set_req(0, load->in(0));
|
load->in(MemNode::Memory),
|
||||||
return this;
|
load->in(MemNode::Address),
|
||||||
|
load->adr_type());
|
||||||
|
ldub = phase->transform(ldub);
|
||||||
|
return new (phase->C, 3) AndINode(ldub, phase->intcon(mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Masking off sign bits? Dont make them!
|
// Masking off sign bits? Dont make them!
|
||||||
|
@ -599,12 +602,21 @@ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
|
if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
|
||||||
const jlong mask = t2->get_con();
|
const jlong mask = t2->get_con();
|
||||||
|
|
||||||
Node *rsh = in(1);
|
Node* in1 = in(1);
|
||||||
uint rop = rsh->Opcode();
|
uint op = in1->Opcode();
|
||||||
|
|
||||||
|
// Masking sign bits off of an integer? Do an unsigned integer to long load.
|
||||||
|
if (op == Op_ConvI2L && in1->in(1)->Opcode() == Op_LoadI && mask == 0x00000000FFFFFFFFL) {
|
||||||
|
Node* load = in1->in(1);
|
||||||
|
return new (phase->C, 3) LoadUI2LNode(load->in(MemNode::Control),
|
||||||
|
load->in(MemNode::Memory),
|
||||||
|
load->in(MemNode::Address),
|
||||||
|
load->adr_type());
|
||||||
|
}
|
||||||
|
|
||||||
// Masking off sign bits? Dont make them!
|
// Masking off sign bits? Dont make them!
|
||||||
if( rop == Op_RShiftL ) {
|
if (op == Op_RShiftL) {
|
||||||
const TypeInt *t12 = phase->type(rsh->in(2))->isa_int();
|
const TypeInt *t12 = phase->type(in1->in(2))->isa_int();
|
||||||
if( t12 && t12->is_con() ) { // Shift is by a constant
|
if( t12 && t12->is_con() ) { // Shift is by a constant
|
||||||
int shift = t12->get_con();
|
int shift = t12->get_con();
|
||||||
shift &= BitsPerJavaLong - 1; // semantics of Java shifts
|
shift &= BitsPerJavaLong - 1; // semantics of Java shifts
|
||||||
|
@ -613,7 +625,7 @@ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
// bits survive. NO sign-extension bits survive the maskings.
|
// bits survive. NO sign-extension bits survive the maskings.
|
||||||
if( (sign_bits_mask & mask) == 0 ) {
|
if( (sign_bits_mask & mask) == 0 ) {
|
||||||
// Use zero-fill shift instead
|
// Use zero-fill shift instead
|
||||||
Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(rsh->in(1),rsh->in(2)));
|
Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(in1->in(1), in1->in(2)));
|
||||||
return new (phase->C, 3) AndLNode( zshift, in(2) );
|
return new (phase->C, 3) AndLNode( zshift, in(2) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -226,6 +226,7 @@ void Type::Initialize_shared(Compile* current) {
|
||||||
TypeInt::CC_LE = TypeInt::make(-1, 0, WidenMin);
|
TypeInt::CC_LE = TypeInt::make(-1, 0, WidenMin);
|
||||||
TypeInt::CC_GE = TypeInt::make( 0, 1, WidenMin); // == TypeInt::BOOL
|
TypeInt::CC_GE = TypeInt::make( 0, 1, WidenMin); // == TypeInt::BOOL
|
||||||
TypeInt::BYTE = TypeInt::make(-128,127, WidenMin); // Bytes
|
TypeInt::BYTE = TypeInt::make(-128,127, WidenMin); // Bytes
|
||||||
|
TypeInt::UBYTE = TypeInt::make(0, 255, WidenMin); // Unsigned Bytes
|
||||||
TypeInt::CHAR = TypeInt::make(0,65535, WidenMin); // Java chars
|
TypeInt::CHAR = TypeInt::make(0,65535, WidenMin); // Java chars
|
||||||
TypeInt::SHORT = TypeInt::make(-32768,32767, WidenMin); // Java shorts
|
TypeInt::SHORT = TypeInt::make(-32768,32767, WidenMin); // Java shorts
|
||||||
TypeInt::POS = TypeInt::make(0,max_jint, WidenMin); // Non-neg values
|
TypeInt::POS = TypeInt::make(0,max_jint, WidenMin); // Non-neg values
|
||||||
|
@ -1022,6 +1023,7 @@ const TypeInt *TypeInt::CC_EQ; // [0] == ZERO
|
||||||
const TypeInt *TypeInt::CC_LE; // [-1,0]
|
const TypeInt *TypeInt::CC_LE; // [-1,0]
|
||||||
const TypeInt *TypeInt::CC_GE; // [0,1] == BOOL (!)
|
const TypeInt *TypeInt::CC_GE; // [0,1] == BOOL (!)
|
||||||
const TypeInt *TypeInt::BYTE; // Bytes, -128 to 127
|
const TypeInt *TypeInt::BYTE; // Bytes, -128 to 127
|
||||||
|
const TypeInt *TypeInt::UBYTE; // Unsigned Bytes, 0 to 255
|
||||||
const TypeInt *TypeInt::CHAR; // Java chars, 0-65535
|
const TypeInt *TypeInt::CHAR; // Java chars, 0-65535
|
||||||
const TypeInt *TypeInt::SHORT; // Java shorts, -32768-32767
|
const TypeInt *TypeInt::SHORT; // Java shorts, -32768-32767
|
||||||
const TypeInt *TypeInt::POS; // Positive 32-bit integers or zero
|
const TypeInt *TypeInt::POS; // Positive 32-bit integers or zero
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -415,6 +415,7 @@ public:
|
||||||
static const TypeInt *CC_LE; // [-1,0]
|
static const TypeInt *CC_LE; // [-1,0]
|
||||||
static const TypeInt *CC_GE; // [0,1] == BOOL (!)
|
static const TypeInt *CC_GE; // [0,1] == BOOL (!)
|
||||||
static const TypeInt *BYTE;
|
static const TypeInt *BYTE;
|
||||||
|
static const TypeInt *UBYTE;
|
||||||
static const TypeInt *CHAR;
|
static const TypeInt *CHAR;
|
||||||
static const TypeInt *SHORT;
|
static const TypeInt *SHORT;
|
||||||
static const TypeInt *POS;
|
static const TypeInt *POS;
|
||||||
|
|
114
hotspot/test/compiler/6797305/Test6797305.java
Normal file
114
hotspot/test/compiler/6797305/Test6797305.java
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 6797305
|
||||||
|
* @summary Add LoadUB and LoadUI opcode class
|
||||||
|
*
|
||||||
|
* @run main/othervm -Xcomp -XX:CompileOnly=Test6797305.loadB,Test6797305.loadB2L,Test6797305.loadUB,Test6797305.loadUBmask,Test6797305.loadUB2L,Test6797305.loadS,Test6797305.loadS2L,Test6797305.loadUS,Test6797305.loadUSmask,Test6797305.loadUS2L,Test6797305.loadI,Test6797305.loadI2L,Test6797305.loadUI2L,Test6797305.loadL Test6797305
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Test6797305 {
|
||||||
|
static final byte[] ba = new byte[] { -1 };
|
||||||
|
static final short[] sa = new short[] { -1 };
|
||||||
|
static final int[] ia = new int[] { -1 };
|
||||||
|
static final long[] la = new long[] { -1 };
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
long b = loadB(ba);
|
||||||
|
if (b != -1)
|
||||||
|
throw new InternalError("loadB failed: " + b + " != " + -1);
|
||||||
|
|
||||||
|
long b2l = loadB2L(ba);
|
||||||
|
if (b2l != -1L)
|
||||||
|
throw new InternalError("loadB2L failed: " + b2l + " != " + -1L);
|
||||||
|
|
||||||
|
int ub = loadUB(ba);
|
||||||
|
if (ub != 0xFF)
|
||||||
|
throw new InternalError("loadUB failed: " + ub + " != " + 0xFF);
|
||||||
|
|
||||||
|
int ubmask = loadUBmask(ba);
|
||||||
|
if (ubmask != 0xFE)
|
||||||
|
throw new InternalError("loadUBmask failed: " + ubmask + " != " + 0xFE);
|
||||||
|
|
||||||
|
long ub2l = loadUB2L(ba);
|
||||||
|
if (ub2l != 0xFFL)
|
||||||
|
throw new InternalError("loadUB2L failed: " + ub2l + " != " + 0xFFL);
|
||||||
|
|
||||||
|
int s = loadS(sa);
|
||||||
|
if (s != -1)
|
||||||
|
throw new InternalError("loadS failed: " + s + " != " + -1);
|
||||||
|
|
||||||
|
long s2l = loadS2L(sa);
|
||||||
|
if (s2l != -1L)
|
||||||
|
throw new InternalError("loadS2L failed: " + s2l + " != " + -1L);
|
||||||
|
|
||||||
|
int us = loadUS(sa);
|
||||||
|
if (us != 0xFFFF)
|
||||||
|
throw new InternalError("loadUS failed: " + us + " != " + 0xFFFF);
|
||||||
|
|
||||||
|
int usmask = loadUSmask(sa);
|
||||||
|
if (usmask != 0xFFFE)
|
||||||
|
throw new InternalError("loadUBmask failed: " + ubmask + " != " + 0xFFFE);
|
||||||
|
|
||||||
|
long us2l = loadUS2L(sa);
|
||||||
|
if (us2l != 0xFFFFL)
|
||||||
|
throw new InternalError("loadUS2L failed: " + us2l + " != " + 0xFFFFL);
|
||||||
|
|
||||||
|
int i = loadI(ia);
|
||||||
|
if (i != -1)
|
||||||
|
throw new InternalError("loadI failed: " + i + " != " + -1);
|
||||||
|
|
||||||
|
long i2l = loadI2L(ia);
|
||||||
|
if (i2l != -1L)
|
||||||
|
throw new InternalError("loadI2L failed: " + i2l + " != " + -1L);
|
||||||
|
|
||||||
|
long ui2l = loadUI2L(ia);
|
||||||
|
if (ui2l != 0xFFFFFFFFL)
|
||||||
|
throw new InternalError("loadUI2L failed: " + ui2l + " != " + 0xFFFFFFFFL);
|
||||||
|
|
||||||
|
long l = loadL(la);
|
||||||
|
if (l != -1L)
|
||||||
|
throw new InternalError("loadL failed: " + l + " != " + -1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int loadB (byte[] ba) { return ba[0]; }
|
||||||
|
static long loadB2L (byte[] ba) { return ba[0]; }
|
||||||
|
static int loadUB (byte[] ba) { return ba[0] & 0xFF; }
|
||||||
|
static int loadUBmask(byte[] ba) { return ba[0] & 0xFE; }
|
||||||
|
static long loadUB2L (byte[] ba) { return ba[0] & 0xFF; }
|
||||||
|
|
||||||
|
static int loadS (short[] sa) { return sa[0]; }
|
||||||
|
static long loadS2L (short[] sa) { return sa[0]; }
|
||||||
|
static int loadUS (short[] sa) { return sa[0] & 0xFFFF; }
|
||||||
|
static int loadUSmask(short[] sa) { return sa[0] & 0xFFFE; }
|
||||||
|
static long loadUS2L (short[] sa) { return sa[0] & 0xFFFF; }
|
||||||
|
|
||||||
|
static int loadI (int[] ia) { return ia[0]; }
|
||||||
|
static long loadI2L (int[] ia) { return ia[0]; }
|
||||||
|
static long loadUI2L (int[] ia) { return ia[0] & 0xFFFFFFFFL; }
|
||||||
|
|
||||||
|
static long loadL (long[] la) { return la[0]; }
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue