diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2012-09-02 20:59:39 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2012-09-02 20:59:39 +0000 |
commit | 6c217a8da45cfc213d392141d81c0ad2f1ea2f44 (patch) | |
tree | 652bed704ab35eef8aa61dee17237944b14b5a9c /compiler/x86/nx86inl.pas | |
parent | feab78ce38c192543c48d3c0c75d5fbf7608de6c (diff) | |
download | fpc-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.pas | 24 |
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. |