40
37
function getresflags(unsigned : boolean) : tresflags;
41
38
procedure left_must_be_reg(opsize:TCGSize;noswap:boolean);
42
39
procedure left_and_right_must_be_fpureg;
43
procedure emit_op_right_left(op:TAsmOp;opsize:TOpSize);
40
procedure emit_op_right_left(op:TAsmOp;opsize:TCgSize);
44
41
procedure emit_generic_code(op:TAsmOp;opsize:TCgSize;unsigned,extra_not,mboverflow:boolean);
46
43
procedure second_cmpfloatsse;
47
44
procedure second_addfloatsse;
48
45
procedure second_mul;virtual;abstract;
50
function first_addstring : tnode; override;
51
procedure second_addstring;override;
52
47
procedure second_addfloat;override;
53
48
procedure second_addsmallset;override;
54
49
procedure second_add64bit;override;
116
108
if (nodetype=subn) and (nf_swaped in flags) then
118
110
if extra_not then
119
emit_reg(A_NOT,TCGSize2Opsize[opsize],left.location.register);
120
r:=cg.getintregister(exprasmlist,OS_INT);
121
cg.a_load_loc_reg(exprasmlist,OS_INT,right.location,r);
111
cg.a_op_reg_reg(exprasmlist,OP_NOT,opsize,left.location.register,left.location.register);
112
r:=cg.getintregister(exprasmlist,opsize);
113
cg.a_load_loc_reg(exprasmlist,opsize,right.location,r);
122
114
emit_reg_reg(op,TCGSize2Opsize[opsize],left.location.register,r);
123
emit_reg_reg(A_MOV,TCGSize2Opsize[opsize],r,left.location.register);
124
cg.ungetregister(exprasmlist,r);
115
cg.a_load_reg_reg(exprasmlist,opsize,opsize,r,left.location.register);
162
153
if extra_not then
164
r:=cg.getintregister(exprasmlist,OS_INT);
165
cg.a_load_loc_reg(exprasmlist,OS_INT,right.location,r);
155
r:=cg.getintregister(exprasmlist,opsize);
156
cg.a_load_loc_reg(exprasmlist,opsize,right.location,r);
166
157
emit_reg(A_NOT,TCGSize2Opsize[opsize],r);
167
158
emit_reg_reg(A_AND,TCGSize2Opsize[opsize],r,left.location.register);
168
cg.ungetregister(exprasmlist,r);
172
emit_op_right_left(op,TCGSize2Opsize[opsize]);
162
emit_op_right_left(op,opsize);
258
procedure tx86addnode.emit_op_right_left(op:TAsmOp;opsize:TOpsize);
245
procedure tx86addnode.emit_op_right_left(op:TAsmOp;opsize:TCgsize);
260
251
{ left must be a register }
261
252
case right.location.loc of
264
exprasmlist.concat(taicpu.op_reg_reg(op,opsize,right.location.register,left.location.register));
255
exprasmlist.concat(taicpu.op_reg_reg(op,TCGSize2Opsize[opsize],right.location.register,left.location.register));
267
exprasmlist.concat(taicpu.op_ref_reg(op,opsize,right.location.reference,left.location.register));
259
tcgx86(cg).make_simple_ref(exprasmlist,right.location.reference);
260
exprasmlist.concat(taicpu.op_ref_reg(op,TCGSize2Opsize[opsize],right.location.reference,left.location.register));
269
exprasmlist.concat(taicpu.op_const_reg(op,opsize,right.location.value,left.location.register));
265
{ x86_64 only supports signed 32 bits constants directly }
266
if (opsize in [OS_S64,OS_64]) and
267
((right.location.value<low(longint)) or (right.location.value>high(longint))) then
269
tmpreg:=cg.getintregister(exprasmlist,opsize);
270
cg.a_load_const_reg(exprasmlist,opsize,right.location.value,tmpreg);
271
exprasmlist.concat(taicpu.op_reg_reg(op,TCGSize2Opsize[opsize],tmpreg,left.location.register));
275
exprasmlist.concat(taicpu.op_const_reg(op,TCGSize2Opsize[opsize],right.location.value,left.location.register));
271
278
internalerror(200203232);
513
515
location_force_mem(exprasmlist,left.location);
514
516
case left.location.loc of
515
517
LOC_REFERENCE,LOC_CREFERENCE:
516
exprasmlist.concat(taicpu.op_ref_reg(op,S_NO,left.location.reference,right.location.register));
519
tcgx86(cg).make_simple_ref(exprasmlist,left.location.reference);
520
exprasmlist.concat(taicpu.op_ref_reg(op,S_NO,left.location.reference,right.location.register));
517
522
LOC_MMREGISTER,LOC_CMMREGISTER:
518
523
exprasmlist.concat(taicpu.op_reg_reg(op,S_NO,left.location.register,right.location.register));
536
541
location_force_mem(exprasmlist,right.location);
537
542
case right.location.loc of
538
543
LOC_REFERENCE,LOC_CREFERENCE:
539
exprasmlist.concat(taicpu.op_ref_reg(op,S_NO,right.location.reference,left.location.register));
545
tcgx86(cg).make_simple_ref(exprasmlist,right.location.reference);
546
exprasmlist.concat(taicpu.op_ref_reg(op,S_NO,right.location.reference,left.location.register));
540
548
LOC_MMREGISTER,LOC_CMMREGISTER:
541
549
exprasmlist.concat(taicpu.op_reg_reg(op,S_NO,right.location.register,left.location.register));
543
551
internalerror(200402223);
546
location_release(exprasmlist,right.location);
547
location_release(exprasmlist,left.location);
548
554
location.resflags:=getresflags(true);
691
689
{*****************************************************************************
693
*****************************************************************************}
695
{ note: if you implemented an fpc_shortstr_concat similar to the }
696
{ one in i386.inc, you have to override first_addstring like in }
697
{ ti386addnode.first_string and implement the shortstring concat }
698
{ manually! The generic routine is different from the i386 one (JM) }
699
function tx86addnode.first_addstring : tnode;
701
{ special cases for shortstrings, handled in pass_2 (JM) }
702
{ can't handle fpc_shortstr_compare with compilerproc either because it }
703
{ returns its results in the flags instead of in eax }
704
if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
705
is_shortstring(left.resulttype.def) and
706
not(((left.nodetype=stringconstn) and (str_length(left)=0)) or
707
((right.nodetype=stringconstn) and (str_length(right)=0))) then
709
expectloc:=LOC_FLAGS;
710
calcregisters(self,0,0,0);
714
{ otherwise, use the generic code }
715
result := inherited first_addstring;
719
procedure tx86addnode.second_addstring;
722
paraloc2 : tparalocation;
724
hregister2 : tregister;
726
{ string operations are not commutative }
727
if nf_swaped in flags then
729
case tstringdef(left.resulttype.def).string_typ of
733
ltn,lten,gtn,gten,equaln,unequaln :
735
paraloc1:=paramanager.getintparaloc(pocall_default,1);
736
paraloc2:=paramanager.getintparaloc(pocall_default,2);
737
{ process parameters }
739
location_release(exprasmlist,left.location);
740
if paraloc2.loc=LOC_REGISTER then
742
hregister2:=cg.getaddressregister(exprasmlist);
743
cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,hregister2);
747
paramanager.allocparaloc(exprasmlist,paraloc2);
748
cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraloc2);
751
location_release(exprasmlist,right.location);
752
if paraloc1.loc=LOC_REGISTER then
754
hregister1:=cg.getaddressregister(exprasmlist);
755
cg.a_loadaddr_ref_reg(exprasmlist,right.location.reference,hregister1);
759
paramanager.allocparaloc(exprasmlist,paraloc1);
760
cg.a_paramaddr_ref(exprasmlist,right.location.reference,paraloc1);
763
if paraloc1.loc=LOC_REGISTER then
765
cg.ungetregister(exprasmlist,hregister2);
766
paramanager.allocparaloc(exprasmlist,paraloc2);
767
cg.a_param_reg(exprasmlist,OS_ADDR,hregister2,paraloc2);
769
if paraloc2.loc=LOC_REGISTER then
771
cg.ungetregister(exprasmlist,hregister1);
772
paramanager.allocparaloc(exprasmlist,paraloc1);
773
cg.a_param_reg(exprasmlist,OS_ADDR,hregister1,paraloc1);
775
paramanager.freeparaloc(exprasmlist,paraloc1);
776
paramanager.freeparaloc(exprasmlist,paraloc2);
777
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
778
cg.a_call_name(exprasmlist,'FPC_SHORTSTR_COMPARE');
779
cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
780
location_freetemp(exprasmlist,left.location);
781
location_freetemp(exprasmlist,right.location);
784
location_reset(location,LOC_FLAGS,OS_NO);
785
location.resflags:=getresflags(true);
788
{ rest should be handled in first pass (JM) }
789
internalerror(200108303);
793
{*****************************************************************************
795
691
*****************************************************************************}
898
793
left_must_be_reg(opsize,false);
899
794
emit_generic_code(A_CMP,opsize,unsigned,false,false);
900
795
location_freetemp(exprasmlist,right.location);
901
location_release(exprasmlist,right.location);
902
if (left.location.loc<>LOC_CREGISTER) then
904
location_freetemp(exprasmlist,left.location);
905
location_release(exprasmlist,left.location);
796
location_freetemp(exprasmlist,left.location);
907
798
location_reset(location,LOC_FLAGS,OS_NO);
908
799
location.resflags:=getresflags(unsigned);
915
806
$Log: nx86add.pas,v $
916
Revision 1.9 2004/02/22 16:30:37 florian
920
Revision 1.8 2004/02/06 16:44:42 florian
921
+ improved floating point compares for x86-64 and Pentium2 and above
923
Revision 1.7 2004/02/04 19:22:27 peter
924
*** empty log message ***
926
Revision 1.6 2004/01/20 12:59:37 florian
927
* common addnode code for x86-64 and i386
929
Revision 1.5 2003/12/26 13:19:16 florian
930
* rtl and compiler compile with -Cfsse2
932
Revision 1.4 2003/12/26 00:32:22 florian
933
+ fpu<->mm register conversion
935
Revision 1.3 2003/12/25 01:07:09 florian
936
+ $fputype directive support
937
+ single data type operations with sse unit
938
* fixed more x86-64 stuff
940
Revision 1.2 2003/12/23 14:38:07 florian
941
+ second_floataddsse implemented
943
Revision 1.1 2003/10/13 01:58:04 florian
944
* some ideas for mm support implemented
807
Revision 1.17 2005/02/14 17:13:10 peter
810
Revision 1.16 2005/02/06 00:05:56 florian