diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index fe91262d8f..0e5bfe8310 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -340,7 +340,12 @@ interface { supported by recent clang-based assemblers for data-in-code } asd_data_region, asd_end_data_region, { ARM } - asd_thumb_func,asd_code + asd_thumb_func,asd_code, + { restricts the assembler only to those instructions, which are + available on the specified CPU; this represents directives such as + NASM's 'CPU 686' or MASM/TASM's '.686p'. Might not be supported by + all assemblers. } + asd_cpu ); TAsmSehDirective=( @@ -376,7 +381,8 @@ interface 'data_region','end_data_region', { ARM } 'thumb_func', - 'code' + 'code', + 'cpu' ); sehdirectivestr : array[TAsmSehDirective] of string[16]=( '.seh_proc','.seh_endproc', diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 8635e49305..22d300b5ba 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -1522,7 +1522,12 @@ implementation procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective); begin - writer.AsmWrite('.'+directivestr[dir]+' '); + { TODO: implement asd_cpu for GAS => usually .arch or .cpu, but the CPU + name has to be translated as well } + if dir=asd_cpu then + writer.AsmWrite(asminfo^.comment+' CPU ') + else + writer.AsmWrite('.'+directivestr[dir]+' '); end; diff --git a/compiler/x86/agx86int.pas b/compiler/x86/agx86int.pas index 352f0a48b3..3e41ad6e02 100644 --- a/compiler/x86/agx86int.pas +++ b/compiler/x86/agx86int.pas @@ -859,6 +859,9 @@ implementation writer.AsmWrite('import '); asd_extern : writer.AsmWrite('EXTRN '); + asd_cpu : + { TODO: implement this properly for TASM/MASM/WASM (.686p, etc.) } + writer.AsmWrite(asminfo^.comment+' CPU '); else internalerror(200509192); end; diff --git a/compiler/x86/agx86nsm.pas b/compiler/x86/agx86nsm.pas index e96a29ecd4..c35d128fe6 100644 --- a/compiler/x86/agx86nsm.pas +++ b/compiler/x86/agx86nsm.pas @@ -80,6 +80,37 @@ interface {$i r386nasm.inc} {$elseif defined(i8086)} {$i r8086nasm.inc} +{$endif} + ); + nasm_cpu_name : array[tcputype] of string = ( +{$if defined(x86_64)} + '', // cpu_none, + 'X64', // cpu_athlon64, + 'X64', // cpu_core_i, + 'X64', // cpu_core_avx, + 'X64' // cpu_core_avx2 +{$elseif defined(i386)} + '', // cpu_none, + '386', // cpu_386, + 'PENTIUM', // cpu_Pentium, + 'P2', // cpu_Pentium2, + 'P3', // cpu_Pentium3, + 'P4', // cpu_Pentium4, + 'P4', // cpu_PentiumM, + 'PRESCOTT', // cpu_core_i, + 'PRESCOTT', // cpu_core_avx, + 'PRESCOTT' // cpu_core_avx2 +{$elseif defined(i8086)} + '', // cpu_none + '8086', // cpu_8086 + '186', // cpu_186 + '286', // cpu_286 + '386', // cpu_386 + 'PENTIUM', // cpu_Pentium + 'P2', // cpu_Pentium2 + 'P3', // cpu_Pentium3 + 'P4', // cpu_Pentium4 + 'P4' // cpu_PentiumM {$endif} ); @@ -641,6 +672,7 @@ interface fixed_opcode: TAsmOp; prefix, LastSecName : string; LastAlign : Byte; + cpu: tcputype; begin if not assigned(p) then exit; @@ -1074,21 +1106,41 @@ interface ait_directive : begin case tai_directive(hp).directive of - asd_nasm_import : - writer.AsmWrite('import '); + asd_nasm_import, asd_extern : - writer.AsmWrite('EXTERN '); + begin + case tai_directive(hp).directive of + asd_nasm_import : + writer.AsmWrite('import '); + asd_extern : + writer.AsmWrite('EXTERN '); + else + internalerror(200509191); + end; + if tai_directive(hp).name<>'' then + begin + + if SmartAsm then + AddSymbol(tai_directive(hp).name,false); + + writer.AsmWrite(tai_directive(hp).name); + end; + end; + asd_cpu : + begin + writer.AsmWrite('CPU '); + for cpu:=low(tcputype) to high(tcputype) do + begin + if tai_directive(hp).name=CPUTypeStr[CPU] then + begin + writer.AsmWriteLn(nasm_cpu_name[cpu]); + break; + end; + end; + end; else internalerror(200509191); end; - if tai_directive(hp).name<>'' then - begin - - if SmartAsm then - AddSymbol(tai_directive(hp).name,false); - - writer.AsmWrite(tai_directive(hp).name); - end; writer.AsmLn; end; ait_seh_directive :