summaryrefslogtreecommitdiff
path: root/compiler/x86/nx86inl.pas
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-09-02 20:59:39 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-09-02 20:59:39 +0000
commit6c217a8da45cfc213d392141d81c0ad2f1ea2f44 (patch)
tree652bed704ab35eef8aa61dee17237944b14b5a9c /compiler/x86/nx86inl.pas
parentfeab78ce38c192543c48d3c0c75d5fbf7608de6c (diff)
downloadfpc-6c217a8da45cfc213d392141d81c0ad2f1ea2f44.tar.gz
* first draft to support the popcnt instruction, works so far for x86 with a real popcnt instruction
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@22289 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/x86/nx86inl.pas')
-rw-r--r--compiler/x86/nx86inl.pas24
1 files changed, 24 insertions, 0 deletions
diff --git a/compiler/x86/nx86inl.pas b/compiler/x86/nx86inl.pas
index b08ca6d007..8bc07edbf5 100644
--- a/compiler/x86/nx86inl.pas
+++ b/compiler/x86/nx86inl.pas
@@ -60,6 +60,7 @@ interface
procedure second_prefetch;override;
procedure second_abs_long;override;
+ procedure second_popcnt;override;
private
procedure load_fpu_location;
end;
@@ -542,4 +543,27 @@ implementation
end;
+ procedure tx86inlinenode.second_popcnt;
+ var
+ opsize: tcgsize;
+ begin
+ secondpass(left);
+
+ opsize:=tcgsize2unsigned[left.location.size];
+
+ { no 8 Bit popcont }
+ if opsize=OS_8 then
+ opsize:=OS_16;
+
+ if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE]) or
+ (left.location.size<>opsize) then
+ hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,hlcg.tcgsize2orddef(opsize),true);
+
+ location_reset(location,LOC_REGISTER,opsize);
+ location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
+ if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
+ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_POPCNT,TCGSize2OpSize[opsize],left.location.register,location.register))
+ else
+ current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_POPCNT,TCGSize2OpSize[opsize],left.location.reference,location.register));
+ end;
end.