Message-Id: Comments: Authenticated sender is From: "Salvador Eduardo Tropea (SET)" Organization: INTI To: djgpp AT delorie DOT com Date: Thu, 27 Aug 1998 17:27:01 +0000 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Constraints Precedence: bulk Here are some notes about gcc constraints in x86 architecture. I want comments, corrections and additions. 1) x86 constraints: 1.1) Classes of registers: NO_REGS AREG /* %eax */ DREG /* %edx */ CREG /* %ecx */ BREG /* %edx */ AD_REGS /* %eax/%edx for DImode */ Q_REGS /* %eax %ebx %ecx %edx */ SIREG /* %esi */ DIREG /* %edi */ INDEX_REGS /* %eax %ebx %ecx %edx %esi %edi %ebp */ GENERAL_REGS /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */ FP_TOP_REG /* %st(0) */ FP_SECOND_REG /* %st(1) */ FLOAT_REGS ALL_REGS LIM_REG_CLASSES 1.2) Then the architecture constraints are: 'r' GENERAL_REGS 'q' Q_REGS 'f' FLOAT_REGS 't' FP_TOP_REG 'u' FP_SECOND_REG 'a' AREG 'b' BREG 'c' CREG 'd' DREG 'A' AD_REGS 'D' DIREG 'S' SIREG 2) The inmediate constraint: This constraint is named 'i' but some times you can't use any inmediate value and you are restricted to a range. If the number is outside the range you must use a register. For this reason the following are defined for x86: 'I' VALUE >= 0 && (VALUE) <= 31 'J' VALUE >= 0 && (VALUE) <= 63 'K' VALUE == 0xff 'L' VALUE == 0xffff 'M' VALUE >= 0 && (VALUE) <= 3 'N' VALUE >= 0 && (VALUE) <= 255 'O' VALUE >= 0 && (VALUE) <= 32 As it could look unclear here is an example: asm("movl %0,%%eax" : : "Ib" (value)); Then if value is in [0..31] we will get: movl $inmediate value,%eax If value is outside: movl $inmediate value,%ebx movl %ebx,%eax The comments say that the use is: I is for non-DImode shifts. J is for DImode shifts. K and L are for an `andsi' optimization. M is for shifts that can be executed by the "lea" opcode. 3) General notes: * You can use a list of constraints, the first match will be used. * The 'm' constraint means memory if you don't use it gcc will force the use of a register, so if the value comes from a variable and goes to a register you'll want to use 'm' to avoid loading a register and then moving it to other. Example: int pp=300; ... asm("movl %0,%%eax" : : "q" (pp)); Could generate: movl _pp,%ebx movl %ebx,%eax but asm("movl %0,%%eax" : : "qm" (pp)); Will generate: movl _pp,%eax * The size of the variables (0,1 ...) can be specified using 'k','w' and 'b'. The default is 'k'. Example: asm("movb %0,(%%esi)" : : "a" (10)); Will generate movb $10,%al movb %eax,(%esi) Wrong of course, but: asm("movb %b0,(%%esi)" : : "a" (10)); Generates movb $10,%al movb %al,(%esi) SET ------------------------------------ 0 -------------------------------- Visit my home page: http://set-soft.home.ml.org/ or http://www.geocities.com/SiliconValley/Vista/6552/ Salvador Eduardo Tropea (SET). (Electronics Engineer) Alternative e-mail: set-soft AT usa DOT net set AT computer DOT org ICQ: 2951574 Address: Curapaligue 2124, Caseros, 3 de Febrero Buenos Aires, (1678), ARGENTINA TE: +(541) 759 0013