diff --git a/docs/cton_domain.py b/docs/cton_domain.py index 3dba386d90..a03acf1160 100644 --- a/docs/cton_domain.py +++ b/docs/cton_domain.py @@ -271,7 +271,10 @@ class InstDocumenter(sphinx.ext.autodoc.Documenter): return False def resolve_name(self, modname, parents, path, base): - return 'base.instructions', [base] + if path: + return path.rstrip('.'), [base] + else: + return 'base.instructions', [base] def format_signature(self): inst = self.object diff --git a/docs/langref.rst b/docs/langref.rst index 49593e3f09..dde7865486 100644 --- a/docs/langref.rst +++ b/docs/langref.rst @@ -775,15 +775,31 @@ the target ISA. .. autoinst:: isplit .. autoinst:: iconcat -Base instruction group -====================== +ISA-specific instructions +========================= + +Target ISAs can define supplemental instructions that do not make sense to +support generally. + +Intel +----- + +Instructions that can only be used by the Intel target ISA. + +.. autoinst:: isa.intel.instructions.sdivmodx +.. autoinst:: isa.intel.instructions.udivmodx + +Instruction groups +================== All of the shared instructions are part of the :instgroup:`base` instruction group. .. autoinstgroup:: base.instructions.GROUP -Target ISAs may define further instructions in their own instruction groups. +Target ISAs may define further instructions in their own instruction groups: + +.. autoinstgroup:: isa.intel.instructions.GROUP Implementation limits ===================== diff --git a/filetests/isa/intel/binary32.cton b/filetests/isa/intel/binary32.cton index 0eb136b5d6..67f37db11b 100644 --- a/filetests/isa/intel/binary32.cton +++ b/filetests/isa/intel/binary32.cton @@ -112,6 +112,19 @@ ebb0: ; asm: imull %ecx, %esi [-,%rsi] v51 = imul v2, v1 ; bin: 0f af f1 + ; asm: movl $1, %eax + [-,%rax] v52 = iconst.i32 1 ; bin: b8 00000001 + ; asm: movl $2, %edx + [-,%rdx] v53 = iconst.i32 2 ; bin: ba 00000002 + ; asm: idivl %ecx + [-,%rax,%rdx] v54, v55 = x86_sdivmodx v52, v53, v1 ; bin: f7 f9 + ; asm: idivl %esi + [-,%rax,%rdx] v56, v57 = x86_sdivmodx v52, v53, v2 ; bin: f7 fe + ; asm: divl %ecx + [-,%rax,%rdx] v58, v59 = x86_udivmodx v52, v53, v1 ; bin: f7 f1 + ; asm: divl %esi + [-,%rax,%rdx] v60, v61 = x86_udivmodx v52, v53, v2 ; bin: f7 f6 + ; Register copies. ; asm: movl %esi, %ecx diff --git a/filetests/isa/intel/binary64.cton b/filetests/isa/intel/binary64.cton index 5e3507d473..bed934d5ab 100644 --- a/filetests/isa/intel/binary64.cton +++ b/filetests/isa/intel/binary64.cton @@ -154,6 +154,21 @@ ebb0: ; asm: imulq %rcx, %r10 [-,%r10] v122 = imul v3, v1 ; bin: 4c 0f af d1 + [-,%rax] v130 = iconst.i64 1 + [-,%rdx] v131 = iconst.i64 2 + ; asm: idivq %rcx + [-,%rax,%rdx] v132, v133 = x86_sdivmodx v130, v131, v1 ; bin: 48 f7 f9 + ; asm: idivq %rsi + [-,%rax,%rdx] v134, v135 = x86_sdivmodx v130, v131, v2 ; bin: 48 f7 fe + ; asm: idivq %r10 + [-,%rax,%rdx] v136, v137 = x86_sdivmodx v130, v131, v3 ; bin: 49 f7 fa + ; asm: divq %rcx + [-,%rax,%rdx] v138, v139 = x86_udivmodx v130, v131, v1 ; bin: 48 f7 f1 + ; asm: divq %rsi + [-,%rax,%rdx] v140, v141 = x86_udivmodx v130, v131, v2 ; bin: 48 f7 f6 + ; asm: divq %r10 + [-,%rax,%rdx] v142, v143 = x86_udivmodx v130, v131, v3 ; bin: 49 f7 f2 + ; Bit-counting instructions. ; asm: popcntq %rsi, %rcx @@ -331,6 +346,21 @@ ebb0: ; asm: imull %ecx, %r10d [-,%r10] v122 = imul v3, v1 ; bin: 44 0f af d1 + [-,%rax] v130 = iconst.i32 1 + [-,%rdx] v131 = iconst.i32 2 + ; asm: idivl %rcx + [-,%rax,%rdx] v132, v133 = x86_sdivmodx v130, v131, v1 ; bin: 40 f7 f9 + ; asm: idivl %rsi + [-,%rax,%rdx] v134, v135 = x86_sdivmodx v130, v131, v2 ; bin: 40 f7 fe + ; asm: idivl %r10d + [-,%rax,%rdx] v136, v137 = x86_sdivmodx v130, v131, v3 ; bin: 41 f7 fa + ; asm: divl %rcx + [-,%rax,%rdx] v138, v139 = x86_udivmodx v130, v131, v1 ; bin: 40 f7 f1 + ; asm: divl %rsi + [-,%rax,%rdx] v140, v141 = x86_udivmodx v130, v131, v2 ; bin: 40 f7 f6 + ; asm: divl %r10d + [-,%rax,%rdx] v142, v143 = x86_udivmodx v130, v131, v3 ; bin: 41 f7 f2 + ; Bit-counting instructions. ; asm: popcntl %esi, %ecx diff --git a/lib/cretonne/meta/isa/intel/defs.py b/lib/cretonne/meta/isa/intel/defs.py index 50251b44af..5078bcec7e 100644 --- a/lib/cretonne/meta/isa/intel/defs.py +++ b/lib/cretonne/meta/isa/intel/defs.py @@ -6,8 +6,9 @@ Commonly used definitions. from __future__ import absolute_import from cdsl.isa import TargetISA, CPUMode import base.instructions +from . import instructions as x86 -ISA = TargetISA('intel', [base.instructions.GROUP]) +ISA = TargetISA('intel', [base.instructions.GROUP, x86.GROUP]) # CPU modes for 32-bit and 64-bit operation. I32 = CPUMode('I32', ISA) diff --git a/lib/cretonne/meta/isa/intel/encodings.py b/lib/cretonne/meta/isa/intel/encodings.py index f6f003bb1e..25421be999 100644 --- a/lib/cretonne/meta/isa/intel/encodings.py +++ b/lib/cretonne/meta/isa/intel/encodings.py @@ -8,6 +8,7 @@ from base.formats import UnaryImm from .defs import I32, I64 from . import recipes as r from . import settings as cfg +from . import instructions as x86 for inst, opc in [ (base.iadd, 0x01), @@ -28,6 +29,14 @@ I64.enc(base.imul.i64, *r.rrx.rex(0x0f, 0xaf, w=1)) I64.enc(base.imul.i32, *r.rrx.rex(0x0f, 0xaf)) I64.enc(base.imul.i32, *r.rrx(0x0f, 0xaf)) +for inst, rrr in [ + (x86.sdivmodx, 7), + (x86.udivmodx, 6)]: + I32.enc(inst.i32, *r.div(0xf7, rrr=rrr)) + I64.enc(inst.i64, *r.div.rex(0xf7, rrr=rrr, w=1)) + I64.enc(inst.i32, *r.div.rex(0xf7, rrr=rrr)) + I64.enc(inst.i32, *r.div(0xf7, rrr=rrr)) + I32.enc(base.copy.i32, *r.umr(0x89)) I64.enc(base.copy.i64, *r.umr.rex(0x89, w=1)) I64.enc(base.copy.i32, *r.umr.rex(0x89)) diff --git a/lib/cretonne/meta/isa/intel/instructions.py b/lib/cretonne/meta/isa/intel/instructions.py new file mode 100644 index 0000000000..a5c2bdafb0 --- /dev/null +++ b/lib/cretonne/meta/isa/intel/instructions.py @@ -0,0 +1,45 @@ +""" +Supplementary instruction definitions for Intel. + +This module defines additional instructions that are useful only to the Intel +target ISA. +""" + +from cdsl.operands import Operand +from cdsl.instructions import Instruction, InstructionGroup +from base.instructions import iB + + +GROUP = InstructionGroup("x86", "Intel-specific instruction set") + +nlo = Operand('nlo', iB, doc='Low part of numerator') +nhi = Operand('nhi', iB, doc='High part of numerator') +d = Operand('d', iB, doc='Denominator') +q = Operand('q', iB, doc='Quotient') +r = Operand('r', iB, doc='Remainder') + +udivmodx = Instruction( + 'x86_udivmodx', r""" + Extended unsigned division. + + Concatenate the bits in `nhi` and `nlo` to form the numerator. + Interpret the bits as an unsigned number and divide by the unsigned + denominator `d`. Trap when `d` is zero or if the quotient is larger + than the range of the output. + + Return both quotient and remainder. + """, + ins=(nlo, nhi, d), outs=(q, r), can_trap=True) + +sdivmodx = Instruction( + 'x86_sdivmodx', r""" + Extended signed division. + + Concatenate the bits in `nhi` and `nlo` to form the numerator. + Interpret the bits as a signed number and divide by the signed + denominator `d`. Trap when `d` is zero or if the quotient is outside + the range of the output. + + Return both quotient and remainder. + """, + ins=(nlo, nhi, d), outs=(q, r), can_trap=True) diff --git a/lib/cretonne/meta/isa/intel/recipes.py b/lib/cretonne/meta/isa/intel/recipes.py index e521b205b1..9c48a529d2 100644 --- a/lib/cretonne/meta/isa/intel/recipes.py +++ b/lib/cretonne/meta/isa/intel/recipes.py @@ -6,7 +6,7 @@ from cdsl.isa import EncRecipe from cdsl.predicates import IsSignedInt, IsEqual from base.formats import Unary, UnaryImm, Binary, BinaryImm, MultiAry from base.formats import Call, IndirectCall, Store, Load -from base.formats import RegMove +from base.formats import RegMove, Ternary from .registers import GPR, ABCD try: @@ -239,6 +239,15 @@ rc = TailRecipe( modrm_r_bits(in_reg0, bits, sink); ''') +# XX /n for division: inputs in %rax, %rdx, r. Outputs in %rax, %rdx. +div = TailRecipe( + 'div', Ternary, size=1, + ins=(GPR.rax, GPR.rdx, GPR), outs=(GPR.rax, GPR.rdx), + emit=''' + PUT_OP(bits, rex1(in_reg2), sink); + modrm_r_bits(in_reg2, bits, sink); + ''') + # XX /n ib with 8-bit immediate sign-extended. rib = TailRecipe( 'rib', BinaryImm, size=2, ins=GPR, outs=0,