compiler: add ##load-vector instruction to avoid wasting a temporary register on x86-32
parent
1b4b66e341
commit
9788323d25
|
@ -29,7 +29,7 @@ INSN: ##load-reference
|
||||||
def: dst/tagged-rep
|
def: dst/tagged-rep
|
||||||
literal: obj ;
|
literal: obj ;
|
||||||
|
|
||||||
! These two are inserted by representation selection
|
! These three are inserted by representation selection
|
||||||
INSN: ##load-tagged
|
INSN: ##load-tagged
|
||||||
def: dst/tagged-rep
|
def: dst/tagged-rep
|
||||||
literal: val ;
|
literal: val ;
|
||||||
|
@ -38,6 +38,10 @@ INSN: ##load-double
|
||||||
def: dst/double-rep
|
def: dst/double-rep
|
||||||
literal: val ;
|
literal: val ;
|
||||||
|
|
||||||
|
INSN: ##load-vector
|
||||||
|
def: dst
|
||||||
|
literal: val rep ;
|
||||||
|
|
||||||
! Stack operations
|
! Stack operations
|
||||||
INSN: ##peek
|
INSN: ##peek
|
||||||
def: dst/tagged-rep
|
def: dst/tagged-rep
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2010 Slava Pestov.
|
! Copyright (C) 2010 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors combinators combinators.short-circuit kernel
|
USING: accessors byte-arrays combinators
|
||||||
layouts locals make math namespaces sequences cpu.architecture
|
combinators.short-circuit kernel layouts locals make math
|
||||||
compiler.cfg.registers
|
namespaces sequences cpu.architecture compiler.cfg.registers
|
||||||
compiler.cfg.instructions
|
compiler.cfg.instructions
|
||||||
compiler.cfg.representations.rewrite
|
compiler.cfg.representations.rewrite
|
||||||
compiler.cfg.representations.selection ;
|
compiler.cfg.representations.selection ;
|
||||||
|
@ -46,11 +46,18 @@ M: ##load-integer optimize-insn
|
||||||
! if the architecture supports it
|
! if the architecture supports it
|
||||||
: convert-to-load-double? ( insn -- ? )
|
: convert-to-load-double? ( insn -- ? )
|
||||||
{
|
{
|
||||||
[ drop load-double? ]
|
[ drop object-immediates? ]
|
||||||
[ dst>> rep-of double-rep? ]
|
[ dst>> rep-of double-rep? ]
|
||||||
[ obj>> float? ]
|
[ obj>> float? ]
|
||||||
} 1&& ;
|
} 1&& ;
|
||||||
|
|
||||||
|
: convert-to-load-vector? ( insn -- ? )
|
||||||
|
{
|
||||||
|
[ drop object-immediates? ]
|
||||||
|
[ dst>> rep-of vector-rep? ]
|
||||||
|
[ obj>> byte-array? ]
|
||||||
|
} 1&& ;
|
||||||
|
|
||||||
! When a literal zeroes/ones vector is unboxed, we replace the ##load-reference
|
! When a literal zeroes/ones vector is unboxed, we replace the ##load-reference
|
||||||
! with a ##zero-vector or ##fill-vector instruction since this is more efficient.
|
! with a ##zero-vector or ##fill-vector instruction since this is more efficient.
|
||||||
: convert-to-zero-vector? ( insn -- ? )
|
: convert-to-zero-vector? ( insn -- ? )
|
||||||
|
@ -65,25 +72,23 @@ M: ##load-integer optimize-insn
|
||||||
[ obj>> B{ 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 } = ]
|
[ obj>> B{ 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 } = ]
|
||||||
} 1&& ;
|
} 1&& ;
|
||||||
|
|
||||||
: (convert-to-load-double) ( insn -- dst val )
|
|
||||||
[ dst>> ] [ obj>> ] bi ; inline
|
|
||||||
|
|
||||||
: (convert-to-zero/fill-vector) ( insn -- dst rep )
|
|
||||||
dst>> dup rep-of ; inline
|
|
||||||
|
|
||||||
M: ##load-reference optimize-insn
|
M: ##load-reference optimize-insn
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
[ dup convert-to-load-double? ]
|
[ dup convert-to-load-double? ]
|
||||||
[ (convert-to-load-double) ##load-double here ]
|
[ [ dst>> ] [ obj>> ] bi ##load-double here ]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
[ dup convert-to-zero-vector? ]
|
[ dup convert-to-zero-vector? ]
|
||||||
[ (convert-to-zero/fill-vector) ##zero-vector here ]
|
[ dst>> dup rep-of ##zero-vector here ]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
[ dup convert-to-fill-vector? ]
|
[ dup convert-to-fill-vector? ]
|
||||||
[ (convert-to-zero/fill-vector) ##fill-vector here ]
|
[ dst>> dup rep-of ##fill-vector here ]
|
||||||
|
}
|
||||||
|
{
|
||||||
|
[ dup convert-to-load-vector? ]
|
||||||
|
[ [ dst>> ] [ obj>> ] [ dst>> rep-of ] tri ##load-vector here ]
|
||||||
}
|
}
|
||||||
[ call-next-method ]
|
[ call-next-method ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
|
@ -78,6 +78,7 @@ CODEGEN: ##load-integer %load-immediate
|
||||||
CODEGEN: ##load-tagged %load-immediate
|
CODEGEN: ##load-tagged %load-immediate
|
||||||
CODEGEN: ##load-reference %load-reference
|
CODEGEN: ##load-reference %load-reference
|
||||||
CODEGEN: ##load-double %load-double
|
CODEGEN: ##load-double %load-double
|
||||||
|
CODEGEN: ##load-vector %load-vector
|
||||||
CODEGEN: ##peek %peek
|
CODEGEN: ##peek %peek
|
||||||
CODEGEN: ##replace %replace
|
CODEGEN: ##replace %replace
|
||||||
CODEGEN: ##inc-d %inc-d
|
CODEGEN: ##inc-d %inc-d
|
||||||
|
|
|
@ -76,6 +76,9 @@ MEMO: cached-string>symbol ( symbol -- obj ) string>symbol ;
|
||||||
: rel-float ( literal class -- )
|
: rel-float ( literal class -- )
|
||||||
[ add-literal ] dip rt-float rel-fixup ;
|
[ add-literal ] dip rt-float rel-fixup ;
|
||||||
|
|
||||||
|
: rel-byte-array ( literal class -- )
|
||||||
|
[ add-literal ] dip rt-byte-array rel-fixup ;
|
||||||
|
|
||||||
: rel-this ( class -- )
|
: rel-this ( class -- )
|
||||||
rt-this rel-fixup ;
|
rt-this rel-fixup ;
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ CONSTANT: rt-cards-offset 10
|
||||||
CONSTANT: rt-decks-offset 11
|
CONSTANT: rt-decks-offset 11
|
||||||
CONSTANT: rt-exception-handler 12
|
CONSTANT: rt-exception-handler 12
|
||||||
CONSTANT: rt-float 13
|
CONSTANT: rt-float 13
|
||||||
|
CONSTANT: rt-byte-array 14
|
||||||
|
|
||||||
: rc-absolute? ( n -- ? )
|
: rc-absolute? ( n -- ? )
|
||||||
${
|
${
|
||||||
|
|
|
@ -225,6 +225,7 @@ HOOK: complex-addressing? cpu ( -- ? )
|
||||||
HOOK: %load-immediate cpu ( reg val -- )
|
HOOK: %load-immediate cpu ( reg val -- )
|
||||||
HOOK: %load-reference cpu ( reg obj -- )
|
HOOK: %load-reference cpu ( reg obj -- )
|
||||||
HOOK: %load-double cpu ( reg val -- )
|
HOOK: %load-double cpu ( reg val -- )
|
||||||
|
HOOK: %load-vector cpu ( reg val rep -- )
|
||||||
|
|
||||||
HOOK: %peek cpu ( vreg loc -- )
|
HOOK: %peek cpu ( vreg loc -- )
|
||||||
HOOK: %replace cpu ( vreg loc -- )
|
HOOK: %replace cpu ( vreg loc -- )
|
||||||
|
@ -500,10 +501,11 @@ M: reg-class param-reg param-regs nth ;
|
||||||
|
|
||||||
M: stack-params param-reg 2drop ;
|
M: stack-params param-reg 2drop ;
|
||||||
|
|
||||||
! Does this architecture support %load-double?
|
! Does this architecture support %load-double, %load-vector and
|
||||||
HOOK: load-double? cpu ( -- ? )
|
! objects in %compare-imm?
|
||||||
|
HOOK: object-immediates? cpu ( -- ? )
|
||||||
|
|
||||||
M: object load-double? f ;
|
M: object object-immediates? f ;
|
||||||
|
|
||||||
! Can this value be an immediate operand for %add-imm, %sub-imm,
|
! Can this value be an immediate operand for %add-imm, %sub-imm,
|
||||||
! or %mul-imm?
|
! or %mul-imm?
|
||||||
|
|
|
@ -27,11 +27,14 @@ M: x86.32 temp-reg ECX ;
|
||||||
M: x86.32 immediate-comparand? ( n -- ? )
|
M: x86.32 immediate-comparand? ( n -- ? )
|
||||||
[ call-next-method ] [ word? ] bi or ;
|
[ call-next-method ] [ word? ] bi or ;
|
||||||
|
|
||||||
M: x86.32 load-double? ( -- ? ) t ;
|
M: x86.32 object-immediates? ( -- ? ) t ;
|
||||||
|
|
||||||
M: x86.32 %load-double ( dst val -- )
|
M: x86.32 %load-double ( dst val -- )
|
||||||
[ 0 [] MOVSD ] dip rc-absolute rel-float ;
|
[ 0 [] MOVSD ] dip rc-absolute rel-float ;
|
||||||
|
|
||||||
|
M:: x86.32 %load-vector ( dst val rep -- )
|
||||||
|
dst 0 [] rep copy-memory* val rc-absolute rel-byte-array ;
|
||||||
|
|
||||||
M: x86.32 %mov-vm-ptr ( reg -- )
|
M: x86.32 %mov-vm-ptr ( reg -- )
|
||||||
0 MOV 0 rc-absolute-cell rel-vm ;
|
0 MOV 0 rc-absolute-cell rel-vm ;
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ void factor_vm::store_external_address(instruction_operand op)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
critical_error("Bad rel type",op.rel_type());
|
critical_error("Bad rel type in store_external_address()",op.rel_type());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,6 +268,9 @@ struct initial_code_block_visitor {
|
||||||
case RT_FLOAT:
|
case RT_FLOAT:
|
||||||
op.store_float(next_literal());
|
op.store_float(next_literal());
|
||||||
break;
|
break;
|
||||||
|
case RT_BYTE_ARRAY:
|
||||||
|
op.store_byte_array(next_literal());
|
||||||
|
break;
|
||||||
case RT_ENTRY_POINT:
|
case RT_ENTRY_POINT:
|
||||||
op.store_value(parent->compute_entry_point_address(next_literal()));
|
op.store_value(parent->compute_entry_point_address(next_literal()));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -114,6 +114,9 @@ struct code_block_compaction_relocation_visitor {
|
||||||
case RT_FLOAT:
|
case RT_FLOAT:
|
||||||
op.store_float(slot_forwarder.visit_pointer(op.load_float(old_offset)));
|
op.store_float(slot_forwarder.visit_pointer(op.load_float(old_offset)));
|
||||||
break;
|
break;
|
||||||
|
case RT_BYTE_ARRAY:
|
||||||
|
op.store_byte_array(slot_forwarder.visit_pointer(op.load_byte_array(old_offset)));
|
||||||
|
break;
|
||||||
case RT_ENTRY_POINT:
|
case RT_ENTRY_POINT:
|
||||||
case RT_ENTRY_POINT_PIC:
|
case RT_ENTRY_POINT_PIC:
|
||||||
case RT_ENTRY_POINT_PIC_TAIL:
|
case RT_ENTRY_POINT_PIC_TAIL:
|
||||||
|
|
|
@ -188,6 +188,9 @@ struct code_block_fixup_relocation_visitor {
|
||||||
case RT_FLOAT:
|
case RT_FLOAT:
|
||||||
op.store_float(data_visitor.visit_pointer(op.load_float(old_offset)));
|
op.store_float(data_visitor.visit_pointer(op.load_float(old_offset)));
|
||||||
break;
|
break;
|
||||||
|
case RT_BYTE_ARRAY:
|
||||||
|
op.store_byte_array(data_visitor.visit_pointer(op.load_byte_array(old_offset)));
|
||||||
|
break;
|
||||||
case RT_ENTRY_POINT:
|
case RT_ENTRY_POINT:
|
||||||
case RT_ENTRY_POINT_PIC:
|
case RT_ENTRY_POINT_PIC:
|
||||||
case RT_ENTRY_POINT_PIC_TAIL:
|
case RT_ENTRY_POINT_PIC_TAIL:
|
||||||
|
|
|
@ -72,6 +72,16 @@ cell instruction_operand::load_float(cell pointer)
|
||||||
return (cell)load_value(pointer) - boxed_float_offset;
|
return (cell)load_value(pointer) - boxed_float_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell instruction_operand::load_byte_array()
|
||||||
|
{
|
||||||
|
return (cell)load_value() - byte_array_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell instruction_operand::load_byte_array(cell pointer)
|
||||||
|
{
|
||||||
|
return (cell)load_value(pointer) - byte_array_offset;
|
||||||
|
}
|
||||||
|
|
||||||
code_block *instruction_operand::load_code_block(cell relative_to)
|
code_block *instruction_operand::load_code_block(cell relative_to)
|
||||||
{
|
{
|
||||||
return ((code_block *)load_value(relative_to) - 1);
|
return ((code_block *)load_value(relative_to) - 1);
|
||||||
|
@ -150,6 +160,11 @@ void instruction_operand::store_float(cell value)
|
||||||
store_value((fixnum)value + boxed_float_offset);
|
store_value((fixnum)value + boxed_float_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void instruction_operand::store_byte_array(cell value)
|
||||||
|
{
|
||||||
|
store_value((fixnum)value + byte_array_offset);
|
||||||
|
}
|
||||||
|
|
||||||
void instruction_operand::store_code_block(code_block *compiled)
|
void instruction_operand::store_code_block(code_block *compiled)
|
||||||
{
|
{
|
||||||
store_value((cell)compiled->entry_point());
|
store_value((cell)compiled->entry_point());
|
||||||
|
|
|
@ -32,6 +32,8 @@ enum relocation_type {
|
||||||
RT_EXCEPTION_HANDLER,
|
RT_EXCEPTION_HANDLER,
|
||||||
/* pointer to a float's payload */
|
/* pointer to a float's payload */
|
||||||
RT_FLOAT,
|
RT_FLOAT,
|
||||||
|
/* pointer to a byte array's payload */
|
||||||
|
RT_BYTE_ARRAY,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,9 +118,10 @@ struct relocation_entry {
|
||||||
case RT_DECKS_OFFSET:
|
case RT_DECKS_OFFSET:
|
||||||
case RT_EXCEPTION_HANDLER:
|
case RT_EXCEPTION_HANDLER:
|
||||||
case RT_FLOAT:
|
case RT_FLOAT:
|
||||||
|
case RT_BYTE_ARRAY:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
critical_error("Bad rel type",rel_type());
|
critical_error("Bad rel type in number_of_parameters()",rel_type());
|
||||||
return -1; /* Can't happen */
|
return -1; /* Can't happen */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,6 +161,8 @@ struct instruction_operand {
|
||||||
fixnum load_value();
|
fixnum load_value();
|
||||||
cell load_float(cell relative_to);
|
cell load_float(cell relative_to);
|
||||||
cell load_float();
|
cell load_float();
|
||||||
|
cell load_byte_array(cell relative_to);
|
||||||
|
cell load_byte_array();
|
||||||
code_block *load_code_block(cell relative_to);
|
code_block *load_code_block(cell relative_to);
|
||||||
code_block *load_code_block();
|
code_block *load_code_block();
|
||||||
|
|
||||||
|
@ -165,6 +170,7 @@ struct instruction_operand {
|
||||||
void store_value_masked(fixnum value, cell mask, cell shift);
|
void store_value_masked(fixnum value, cell mask, cell shift);
|
||||||
void store_value(fixnum value);
|
void store_value(fixnum value);
|
||||||
void store_float(cell value);
|
void store_float(cell value);
|
||||||
|
void store_byte_array(cell value);
|
||||||
void store_code_block(code_block *compiled);
|
void store_code_block(code_block *compiled);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,8 @@ struct bignum : public object {
|
||||||
cell *data() const { return (cell *)(this + 1); }
|
cell *data() const { return (cell *)(this + 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const cell byte_array_offset = 16 - BYTE_ARRAY_TYPE;
|
||||||
|
|
||||||
struct byte_array : public object {
|
struct byte_array : public object {
|
||||||
static const cell type_number = BYTE_ARRAY_TYPE;
|
static const cell type_number = BYTE_ARRAY_TYPE;
|
||||||
static const cell element_size = 1;
|
static const cell element_size = 1;
|
||||||
|
|
|
@ -200,6 +200,9 @@ struct literal_references_visitor {
|
||||||
case RT_FLOAT:
|
case RT_FLOAT:
|
||||||
op.store_float(visitor->visit_pointer(op.load_float()));
|
op.store_float(visitor->visit_pointer(op.load_float()));
|
||||||
break;
|
break;
|
||||||
|
case RT_BYTE_ARRAY:
|
||||||
|
op.store_byte_array(visitor->visit_pointer(op.load_byte_array()));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue