1 1.1.1.2 mrg Copyright 2000-2005 Free Software Foundation, Inc. 2 1.1 mrg 3 1.1 mrg This file is part of the GNU MP Library. 4 1.1 mrg 5 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify 6 1.1.1.2 mrg it under the terms of either: 7 1.1.1.2 mrg 8 1.1.1.2 mrg * the GNU Lesser General Public License as published by the Free 9 1.1.1.2 mrg Software Foundation; either version 3 of the License, or (at your 10 1.1.1.2 mrg option) any later version. 11 1.1.1.2 mrg 12 1.1.1.2 mrg or 13 1.1.1.2 mrg 14 1.1.1.2 mrg * the GNU General Public License as published by the Free Software 15 1.1.1.2 mrg Foundation; either version 2 of the License, or (at your option) any 16 1.1.1.2 mrg later version. 17 1.1.1.2 mrg 18 1.1.1.2 mrg or both in parallel, as here. 19 1.1 mrg 20 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but 21 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 22 1.1.1.2 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23 1.1.1.2 mrg for more details. 24 1.1 mrg 25 1.1.1.2 mrg You should have received copies of the GNU General Public License and the 26 1.1.1.2 mrg GNU Lesser General Public License along with the GNU MP Library. If not, 27 1.1.1.2 mrg see https://www.gnu.org/licenses/. 28 1.1 mrg 29 1.1 mrg 30 1.1 mrg 31 1.1 mrg IA-64 MPN SUBROUTINES 32 1.1 mrg 33 1.1 mrg 34 1.1 mrg This directory contains mpn functions for the IA-64 architecture. 35 1.1 mrg 36 1.1 mrg 37 1.1 mrg CODE ORGANIZATION 38 1.1 mrg 39 1.1 mrg mpn/ia64 itanium-2, and generic ia64 40 1.1 mrg 41 1.1 mrg The code here has been optimized primarily for Itanium 2. Very few Itanium 1 42 1.1 mrg chips were ever sold, and Itanium 2 is more powerful, so the latter is what 43 1.1 mrg we concentrate on. 44 1.1 mrg 45 1.1 mrg 46 1.1 mrg 47 1.1 mrg CHIP NOTES 48 1.1 mrg 49 1.1 mrg The IA-64 ISA keeps instructions three and three in 128 bit bundles. 50 1.1 mrg Programmers/compilers need to put explicit breaks `;;' when there are WAW or 51 1.1 mrg RAW dependencies, with some notable exceptions. Such "breaks" are typically 52 1.1 mrg at the end of a bundle, but can be put between operations within some bundle 53 1.1 mrg types too. 54 1.1 mrg 55 1.1 mrg The Itanium 1 and Itanium 2 implementations can under ideal conditions 56 1.1 mrg execute two bundles per cycle. The Itanium 1 allows 4 of these instructions 57 1.1 mrg to do integer operations, while the Itanium 2 allows all 6 to be integer 58 1.1 mrg operations. 59 1.1 mrg 60 1.1 mrg Taken cloop branches seem to insert a bubble into the pipeline most of the 61 1.1 mrg time on Itanium 1. 62 1.1 mrg 63 1.1 mrg Loads to the fp registers bypass the L1 cache and thus get extremely long 64 1.1 mrg latencies, 9 cycles on the Itanium 1 and 6 cycles on the Itanium 2. 65 1.1 mrg 66 1.1 mrg The software pipeline stuff using br.ctop instruction causes delays, since 67 1.1 mrg many issue slots are taken up by instructions with zero predicates, and 68 1.1 mrg since many extra instructions are needed to set things up. These features 69 1.1 mrg are clearly designed for code density, not speed. 70 1.1 mrg 71 1.1 mrg Misc pipeline limitations (Itanium 1): 72 1.1 mrg * The getf.sig instruction can only execute in M0. 73 1.1 mrg * At most four integer instructions/cycle. 74 1.1 mrg * Nops take up resources like any plain instructions. 75 1.1 mrg 76 1.1 mrg Misc pipeline limitations (Itanium 2): 77 1.1 mrg * The getf.sig instruction can only execute in M0. 78 1.1 mrg * Nops take up resources like any plain instructions. 79 1.1 mrg 80 1.1 mrg 81 1.1 mrg ASSEMBLY SYNTAX 82 1.1 mrg 83 1.1 mrg .align pads with nops in a text segment, but gas 2.14 and earlier 84 1.1 mrg incorrectly byte-swaps its nop bundle in big endian mode (eg. hpux), making 85 1.1 mrg it come out as break instructions. We use the ALIGN() macro in 86 1.1 mrg mpn/ia64/ia64-defs.m4 when it might be executed across. That macro 87 1.1 mrg suppresses any .align if the problem is detected by configure. Lack of 88 1.1 mrg alignment might hurt performance but will at least be correct. 89 1.1 mrg 90 1.1 mrg foo:: to create a global symbol is not accepted by gas. Use separate 91 1.1 mrg ".global foo" and "foo:" instead. 92 1.1 mrg 93 1.1 mrg .global is the standard global directive. gas accepts .globl, but hpux "as" 94 1.1 mrg doesn't. 95 1.1 mrg 96 1.1 mrg .proc / .endp generates the appropriate .type and .size information for ELF, 97 1.1 mrg so the latter directives don't need to be given explicitly. 98 1.1 mrg 99 1.1 mrg .pred.rel "mutex"... is standard for annotating predicate register 100 1.1 mrg relationships. gas also accepts .pred.rel.mutex, but hpux "as" doesn't. 101 1.1 mrg 102 1.1 mrg .pred directives can't be put on a line with a label, like 103 1.1 mrg ".Lfoo: .pred ...", the HP assembler on HP-UX 11.23 rejects that. 104 1.1 mrg gas is happy with it, and past versions of HP had seemed ok. 105 1.1 mrg 106 1.1 mrg // is the standard comment sequence, but we prefer "C" since it inhibits m4 107 1.1 mrg macro expansion. See comments in ia64-defs.m4. 108 1.1 mrg 109 1.1 mrg 110 1.1 mrg REGISTER USAGE 111 1.1 mrg 112 1.1 mrg Special: 113 1.1 mrg r0: constant 0 114 1.1 mrg r1: global pointer (gp) 115 1.1 mrg r8: return value 116 1.1 mrg r12: stack pointer (sp) 117 1.1 mrg r13: thread pointer (tp) 118 1.1 mrg Caller-saves: r8-r11 r14-r31 f6-f15 f32-f127 119 1.1 mrg Caller-saves but rotating: r32- 120 1.1 mrg 121 1.1 mrg 122 1.1 mrg ================================================================ 123 1.1 mrg mpn_add_n, mpn_sub_n: 124 1.1 mrg 125 1.1 mrg The current code runs at 1.25 c/l on Itanium 2. 126 1.1 mrg 127 1.1 mrg ================================================================ 128 1.1 mrg mpn_mul_1: 129 1.1 mrg 130 1.1 mrg The current code runs at 2 c/l on Itanium 2. 131 1.1 mrg 132 1.1 mrg Using a blocked approach, working off of 4 separate places in the operands, 133 1.1 mrg one could make use of the xma accumulation, and approach 1 c/l. 134 1.1 mrg 135 1.1 mrg ldf8 [up] 136 1.1 mrg xma.l 137 1.1 mrg xma.hu 138 1.1 mrg stf8 [wrp] 139 1.1 mrg 140 1.1 mrg ================================================================ 141 1.1 mrg mpn_addmul_1: 142 1.1 mrg 143 1.1 mrg The current code runs at 2 c/l on Itanium 2. 144 1.1 mrg 145 1.1 mrg It seems possible to use a blocked approach, as with mpn_mul_1. We should 146 1.1 mrg read rp[] to integer registers, allowing for just one getf.sig per cycle. 147 1.1 mrg 148 1.1 mrg ld8 [rp] 149 1.1 mrg ldf8 [up] 150 1.1 mrg xma.l 151 1.1 mrg xma.hu 152 1.1 mrg getf.sig 153 1.1 mrg add+add+cmp+cmp 154 1.1 mrg st8 [wrp] 155 1.1 mrg 156 1.1 mrg These 10 instructions can be scheduled to approach 1.667 cycles, and with 157 1.1 mrg the 4 cycle latency of xma, this means we need at least 3 blocks. Using 158 1.1 mrg ldfp8 we could approach 1.583 c/l. 159 1.1 mrg 160 1.1 mrg ================================================================ 161 1.1 mrg mpn_submul_1: 162 1.1 mrg 163 1.1 mrg The current code runs at 2.25 c/l on Itanium 2. Getting to 2 c/l requires 164 1.1 mrg ldfp8 with all alignment headache that implies. 165 1.1 mrg 166 1.1 mrg ================================================================ 167 1.1 mrg mpn_addmul_N 168 1.1 mrg 169 1.1.1.2 mrg For best speed, we need to give up using mpn_addmul_2 as the main multiply 170 1.1 mrg building block, and instead take multiple v limbs per loop. For the Itanium 171 1.1 mrg 1, we need to take about 8 limbs at a time for full speed. For the Itanium 172 1.1 mrg 2, something like mpn_addmul_4 should be enough. 173 1.1 mrg 174 1.1 mrg The add+cmp+cmp+add we use on the other codes is optimal for shortening 175 1.1 mrg recurrencies (1 cycle) but the sequence takes up 4 execution slots. When 176 1.1 mrg recurrency depth is not critical, a more standard 3-cycle add+cmp+add is 177 1.1 mrg better. 178 1.1 mrg 179 1.1 mrg /* First load the 8 values from v */ 180 1.1 mrg ldfp8 v0, v1 = [r35], 16;; 181 1.1 mrg ldfp8 v2, v3 = [r35], 16;; 182 1.1 mrg ldfp8 v4, v5 = [r35], 16;; 183 1.1 mrg ldfp8 v6, v7 = [r35], 16;; 184 1.1 mrg 185 1.1 mrg /* In the inner loop, get a new U limb and store a result limb. */ 186 1.1 mrg mov lc = un 187 1.1 mrg Loop: ldf8 u0 = [r33], 8 188 1.1 mrg ld8 r0 = [r32] 189 1.1 mrg xma.l lp0 = v0, u0, hp0 190 1.1 mrg xma.hu hp0 = v0, u0, hp0 191 1.1 mrg xma.l lp1 = v1, u0, hp1 192 1.1 mrg xma.hu hp1 = v1, u0, hp1 193 1.1 mrg xma.l lp2 = v2, u0, hp2 194 1.1 mrg xma.hu hp2 = v2, u0, hp2 195 1.1 mrg xma.l lp3 = v3, u0, hp3 196 1.1 mrg xma.hu hp3 = v3, u0, hp3 197 1.1 mrg xma.l lp4 = v4, u0, hp4 198 1.1 mrg xma.hu hp4 = v4, u0, hp4 199 1.1 mrg xma.l lp5 = v5, u0, hp5 200 1.1 mrg xma.hu hp5 = v5, u0, hp5 201 1.1 mrg xma.l lp6 = v6, u0, hp6 202 1.1 mrg xma.hu hp6 = v6, u0, hp6 203 1.1 mrg xma.l lp7 = v7, u0, hp7 204 1.1 mrg xma.hu hp7 = v7, u0, hp7 205 1.1 mrg getf.sig l0 = lp0 206 1.1 mrg getf.sig l1 = lp1 207 1.1 mrg getf.sig l2 = lp2 208 1.1 mrg getf.sig l3 = lp3 209 1.1 mrg getf.sig l4 = lp4 210 1.1 mrg getf.sig l5 = lp5 211 1.1 mrg getf.sig l6 = lp6 212 1.1 mrg add+cmp+add xx, l0, r0 213 1.1 mrg add+cmp+add acc0, acc1, l1 214 1.1 mrg add+cmp+add acc1, acc2, l2 215 1.1 mrg add+cmp+add acc2, acc3, l3 216 1.1 mrg add+cmp+add acc3, acc4, l4 217 1.1 mrg add+cmp+add acc4, acc5, l5 218 1.1 mrg add+cmp+add acc5, acc6, l6 219 1.1 mrg getf.sig acc6 = lp7 220 1.1 mrg st8 [r32] = xx, 8 221 1.1 mrg br.cloop Loop 222 1.1 mrg 223 1.1 mrg 49 insn at max 6 insn/cycle: 8.167 cycles/limb8 224 1.1 mrg 11 memops at max 2 memops/cycle: 5.5 cycles/limb8 225 1.1 mrg 16 fpops at max 2 fpops/cycle: 8 cycles/limb8 226 1.1 mrg 21 intops at max 4 intops/cycle: 5.25 cycles/limb8 227 1.1 mrg 11+21 memops+intops at max 4/cycle 8 cycles/limb8 228 1.1 mrg 229 1.1 mrg ================================================================ 230 1.1 mrg mpn_lshift, mpn_rshift 231 1.1 mrg 232 1.1 mrg The current code runs at 1 cycle/limb on Itanium 2. 233 1.1 mrg 234 1.1 mrg Using 63 separate loops, we could use the double-word shrp instruction. 235 1.1 mrg That instruction has a plain single-cycle latency. We need 63 loops since 236 1.1 mrg this instruction only accept immediate count. That would lead to a somewhat 237 1.1 mrg silly code size, but the speed would be 0.75 c/l on Itanium 2 (by using shrp 238 1.1 mrg each cycle plus shl/shr going down I1 for a further limb every second 239 1.1 mrg cycle). 240 1.1 mrg 241 1.1 mrg ================================================================ 242 1.1 mrg mpn_copyi, mpn_copyd 243 1.1 mrg 244 1.1 mrg The current code runs at 0.5 c/l on Itanium 2. But that is just for L1 245 1.1 mrg cache hit. The 4-way unrolled loop takes just 2 cycles, and thus load-use 246 1.1 mrg scheduling isn't great. It might be best to actually use modulo scheduled 247 1.1 mrg loops, since that will allow us to do better load-use scheduling without too 248 1.1 mrg much unrolling. 249 1.1 mrg 250 1.1 mrg Depending on size or operand alignment, we get 1 c/l or 0.5 c/l on Itanium 251 1.1 mrg 2, according to tune/speed. Cache bank conflicts? 252 1.1 mrg 253 1.1 mrg 254 1.1 mrg 255 1.1 mrg REFERENCES 256 1.1 mrg 257 1.1 mrg Intel Itanium Architecture Software Developer's Manual, volumes 1 to 3, 258 1.1 mrg Intel document 245317-004, 245318-004, 245319-004 October 2002. Volume 1 259 1.1 mrg includes an Itanium optimization guide. 260 1.1 mrg 261 1.1 mrg Intel Itanium Processor-specific Application Binary Interface (ABI), Intel 262 1.1 mrg document 245370-003, May 2001. Describes C type sizes, dynamic linking, 263 1.1 mrg etc. 264 1.1 mrg 265 1.1 mrg Intel Itanium Architecture Assembly Language Reference Guide, Intel document 266 1.1 mrg 248801-004, 2000-2002. Describes assembly instruction syntax and other 267 1.1 mrg directives. 268 1.1 mrg 269 1.1 mrg Itanium Software Conventions and Runtime Architecture Guide, Intel document 270 1.1 mrg 245358-003, May 2001. Describes calling conventions, including stack 271 1.1 mrg unwinding requirements. 272 1.1 mrg 273 1.1 mrg Intel Itanium Processor Reference Manual for Software Optimization, Intel 274 1.1 mrg document 245473-003, November 2001. 275 1.1 mrg 276 1.1 mrg Intel Itanium-2 Processor Reference Manual for Software Development and 277 1.1 mrg Optimization, Intel document 251110-003, May 2004. 278 1.1 mrg 279 1.1 mrg All the above documents can be found online at 280 1.1 mrg 281 1.1 mrg http://developer.intel.com/design/itanium/manuals.htm 282