浏览代码

Use macros to include the inline assembly instead of inline functions

The new nvcc version 4 no longer allows registers to be declared at
module scope, so we need to do all the work that uses them inside
one function.  Have cios.asm now provide macros instead of functions
to do all the asm work.
Ian Goldberg 14 年之前
父节点
当前提交
771b13c42c
共有 3 个文件被更改,包括 186 次插入194 次删除
  1. 5 9
      dpstream.cu
  2. 167 175
      gencios_reg_20
  3. 14 10
      parrhoasm.cu

+ 5 - 9
dpstream.cu

@@ -61,30 +61,26 @@ void DPstreamEnd(void)
     DPbuffer_device = NULL;
     DPbuffer_device = NULL;
 }
 }
 
 
-__device__ inline void write_dp(unsigned int*, unsigned int, unsigned int,
-    unsigned int, unsigned int, unsigned int, unsigned int);
-
 // Call this from the device to write the following into the buffer:
 // Call this from the device to write the following into the buffer:
 //   block and thread indices (1 word total)
 //   block and thread indices (1 word total)
 //   x (WORDS words)
 //   x (WORDS words)
 //   a (2 words)
 //   a (2 words)
 //   b (2 words)
 //   b (2 words)
-__device__ inline void DPstreamWrite(unsigned int a_0, unsigned int a_1,
+__device__ inline unsigned int *DPstreamWrite(unsigned int a_0, unsigned int a_1,
     unsigned int a_2, unsigned int b_0, unsigned int b_1, unsigned int b_2)
     unsigned int a_2, unsigned int b_0, unsigned int b_1, unsigned int b_2)
 {
 {
-    if (!DPbuffer) return;
+    if (!DPbuffer) return NULL;
 
 
     // Atomically increment the DPbuffertail
     // Atomically increment the DPbuffertail
-    if (DPbuffertail >= DPbuffersize) return;
+    if (DPbuffertail >= DPbuffersize) return NULL;
     unsigned int ouroffset = atomicAdd((unsigned int *)&DPbuffertail,
     unsigned int ouroffset = atomicAdd((unsigned int *)&DPbuffertail,
 		(unsigned int) (DPrecordsize));
 		(unsigned int) (DPrecordsize));
     if (ouroffset + DPrecordsize > DPbuffersize) {
     if (ouroffset + DPrecordsize > DPbuffersize) {
 	atomicSub((unsigned int *)&DPbuffertail, (unsigned int)DPrecordsize);
 	atomicSub((unsigned int *)&DPbuffertail, (unsigned int)DPrecordsize);
-	return;
+	return NULL;
     }
     }
     unsigned int *ourbuffer = DPbuffer + ouroffset;
     unsigned int *ourbuffer = DPbuffer + ouroffset;
-
-    write_dp(ourbuffer, a_0, a_1, a_2, b_0, b_1, b_2);
+    return ourbuffer;
 }
 }
 
 
 static void dpcallback(void *data, unsigned short threadId,
 static void dpcallback(void *data, unsigned short threadId,

+ 167 - 175
gencios_reg_20

@@ -32,296 +32,288 @@ my $i;
 ## scope
 ## scope
 
 
 print <<EOA;
 print <<EOA;
-// An evil hack that declares a bunch of registers in the module scope
-__device__ __noinline__ void evilhack() {
-    asm("ret;}\\n"
-        ".reg.u32 \$xr<$WORDSp1>;\\n"
-        ".reg.u32 \$cg<$WORDS>;\\n"
-        ".reg.u32 \$cy<$WORDS>;\\n"
-	".reg.u32 \$yi,\$crp,\$m;\\n"
-	".reg.u64 \$cs,\$ct;\\n"
-	".reg.u32 \$zr<$WORDSp2>;\\n"
-	".reg.u32 \$crho<$WORDS>;\\n"
-	".func hackend {\\n"
-EOA
-print "\t\"ret.uni;\\n\"\n";
+#define CIOS_REG_DECLARE \\
+    asm volatile ( \\
+        ".reg.u32 \$xr<$WORDSp1>;\\n" \\
+        ".reg.u32 \$cg<$WORDS>;\\n" \\
+        ".reg.u32 \$cy<$WORDS>;\\n" \\
+	".reg.u32 \$yi,\$crp,\$m;\\n" \\
+	".reg.u64 \$cs,\$ct;\\n" \\
+	".reg.u32 \$zr<$WORDSp2>;\\n" \\
+	".reg.u32 \$crho<$WORDS>;\\n" \\
+    )
 
 
-print "    );\n";
-print "}\n";
+EOA
 
 
 print <<'EOA';
 print <<'EOA';
-__device__ inline void loadx(unsigned int *x)
-{
-    asm(
+#define CIOS_LOADX(x) \
+    asm volatile ( \
 EOA
 EOA
 
 
 for ($i=0;$i<$WORDS;++$i) {
 for ($i=0;$i<$WORDS;++$i) {
     my $xoff = $i*4;
     my $xoff = $i*4;
-    print "\t\"ld.global.u32 \$xr$i, [%0+$xoff];\\n\"\n";
+    print "\t\"ld.global.u32 \$xr$i, [%0+$xoff];\\n\" \\\n";
 }
 }
-print "\t\"// Load c_rho into registers\\n\"\n";
+print "\t\"// Load c_rho into registers\\n\" \\\n";
 my ($xoff, $xoffm1);
 my ($xoff, $xoffm1);
 my $croff;
 my $croff;
 for($i=0;$i<$WORDS;++$i) {
 for($i=0;$i<$WORDS;++$i) {
     $croff = $i*4;
     $croff = $i*4;
-    print "\t\"ld.const.u32 \$crho$i, [c_rho+$croff];\\n\"\n";
+    print "\t\"ld.const.u32 \$crho$i, [c_rho+$croff];\\n\" \\\n";
 }
 }
-print "\t\"mov.u32 \$crp, %1;\\n\"\n";
-print "\t\"// Load c_g into registers\\n\"\n";
+print "\t\"mov.u32 \$crp, %1;\\n\" \\\n";
+print "\t\"// Load c_g into registers\\n\" \\\n";
 for($i=0;$i<$WORDS;++$i) {
 for($i=0;$i<$WORDS;++$i) {
     $croff = $i*4;
     $croff = $i*4;
-    print "\t\"ld.const.u32 \$cg$i, [c_g+$croff];\\n\"\n";
+    print "\t\"ld.const.u32 \$cg$i, [c_g+$croff];\\n\" \\\n";
 }
 }
-print "\t\"// Load c_y into registers\\n\"\n";
+print "\t\"// Load c_y into registers\\n\" \\\n";
 for($i=0;$i<$WORDS;++$i) {
 for($i=0;$i<$WORDS;++$i) {
     $croff = $i*4;
     $croff = $i*4;
-    print "\t\"ld.const.u32 \$cy$i, [c_y+$croff];\\n\"\n";
+    print "\t\"ld.const.u32 \$cy$i, [c_y+$croff];\\n\" \\\n";
 }
 }
 
 
 
 
 print <<'EOA';
 print <<'EOA';
-    : : "l" (x), "r" (c_rho_prime));
-}
+    : : "l" (x), "r" (c_rho_prime))
 
 
-__device__ inline void savex(unsigned int *x)
-{
-    asm(
+EOA
+
+print <<'EOA';
+#define CIOS_SAVEX(x) \
+    asm volatile ( \
 EOA
 EOA
 
 
 for ($i=0;$i<$WORDS;++$i) {
 for ($i=0;$i<$WORDS;++$i) {
     my $xoff = $i*4;
     my $xoff = $i*4;
-    print "\t\"st.global.u32 [%0+$xoff], \$xr$i;\\n\"\n";
+    print "\t\"st.global.u32 [%0+$xoff], \$xr$i;\\n\" \\\n";
 }
 }
 
 
 print <<'EOA';
 print <<'EOA';
-    : : "l" (x));
-}
+    : : "l" (x))
+
 EOA
 EOA
 
 
 print <<'EOA';
 print <<'EOA';
-__device__ void modmul(int multtype)
 // x <- (x * y) * r_inv   (mod rho);
 // x <- (x * y) * r_inv   (mod rho);
 // where y is (multtype == 0 ? c_g : multtype == 1 ? c_y : x)
 // where y is (multtype == 0 ? c_g : multtype == 1 ? c_y : x)
-{
-    asm(
-    ".reg.pred $mtp0,$mtp1;\n"
+#define CIOS_MODMUL(multtype) \
+    asm volatile ( \
+    ".reg.pred $mtp0,$mtp1;\n" \
 EOA
 EOA
-print "    \".reg.pred \$retaddr<", $WORDS-2, ">;\\n\"\n";
+print "    \".reg.pred \$retaddr<", $WORDS-2, ">;\\n\" \\\n";
 print <<'EOA';
 print <<'EOA';
-    "mov.u32 $m, 0;\n"
-    "setp.eq.u32 $mtp0, %0, $m;\n"
-    "mov.u32 $m, 1;\n"
-    "setp.eq.u32 $mtp1, %0, $m;\n"
-    : : "r" (multtype));
+    "mov.u32 $m, 0;\n" \
+    "setp.eq.u32 $mtp0, %0, $m;\n" \
+    "mov.u32 $m, 1;\n" \
+    "setp.eq.u32 $mtp1, %0, $m;\n" \
+    : : "r" (multtype)); \
 EOA
 EOA
 
 
-print "    asm(\n";
-print "\t\"// First iteration: i=0 and z is unset\\n\"\n";
+print "    asm volatile ( \\\n";
+print "\t\"// First iteration: i=0 and z is unset\\n\" \\\n";
 
 
 # Pick the correct value of $yi
 # Pick the correct value of $yi
-print "\t\"selp.u32 \$yi, \$cg0, \$xr0, \$mtp0;\\n\"\n";
-print "\t\"selp.u32 \$yi, \$cy0, \$yi, \$mtp1;\\n\"\n";
+print "\t\"selp.u32 \$yi, \$cg0, \$xr0, \$mtp0;\\n\" \\\n";
+print "\t\"selp.u32 \$yi, \$cy0, \$yi, \$mtp1;\\n\" \\\n";
 
 
-print "\t\"mul.wide.u32 \$cs, \$xr0, \$yi;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr0, \$cs;\\n\"\n";
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
+print "\t\"mul.wide.u32 \$cs, \$xr0, \$yi;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr0, \$cs;\\n\" \\\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
 
 
 for($i=1; $i<$WORDS; ++$i) {
 for($i=1; $i<$WORDS; ++$i) {
     $xoff = $i*32*4;
     $xoff = $i*32*4;
-    print "\t\"mad.wide.u32 \$cs, \$xr$i, \$yi, \$cs;\\n\"\n";
-    print "\t\"cvt.u32.u64 \$zr$i, \$cs;\\n\"\n";
-    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
+    print "\t\"mad.wide.u32 \$cs, \$xr$i, \$yi, \$cs;\\n\" \\\n";
+    print "\t\"cvt.u32.u64 \$zr$i, \$cs;\\n\" \\\n";
+    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
 }
 }
-print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\"\n";
+print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\" \\\n";
 
 
-print "\t\"mul.lo.u32 \$m, \$zr0, \$crp;\\n\"\n";
-print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\"\n";
-print "\t\"mad.wide.u32 \$cs, \$m, \$crho0, \$ct;\\n\"\n";
+print "\t\"mul.lo.u32 \$m, \$zr0, \$crp;\\n\" \\\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\" \\\n";
+print "\t\"mad.wide.u32 \$cs, \$m, \$crho0, \$ct;\\n\" \\\n";
 
 
 for($i=1;$i<$WORDS;++$i) {
 for($i=1;$i<$WORDS;++$i) {
     my $im1 = ($i-1);
     my $im1 = ($i-1);
-    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\"\n";
-    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-    print "\t\"mad.wide.u32 \$cs, \$m, \$crho$i, \$cs;\\n\"\n";
-    print "\t\"cvt.u32.u64 \$zr$im1, \$cs;\\n\"\n";
+    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\" \\\n";
+    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+    print "\t\"mad.wide.u32 \$cs, \$m, \$crho$i, \$cs;\\n\" \\\n";
+    print "\t\"cvt.u32.u64 \$zr$im1, \$cs;\\n\" \\\n";
 }
 }
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\"\n";
-print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr$WORDSm1, \$cs;\\n\"\n";
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\"\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\" \\\n";
+print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr$WORDSm1, \$cs;\\n\" \\\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\" \\\n";
 
 
 my $j;
 my $j;
 for ($j=1; $j<$WORDS-1; ++$j) {
 for ($j=1; $j<$WORDS-1; ++$j) {
 
 
 print <<'EOA';
 print <<'EOA';
-	"// Middle iterations\n"
+	"// Middle iterations\n" \
 EOA
 EOA
 
 
 # Pick the correct value of $yi
 # Pick the correct value of $yi
 my $yioff = $j*4;
 my $yioff = $j*4;
-print "\t\"selp.u32 \$yi, \$cg$j, \$xr$j, \$mtp0;\\n\"\n";
-print "\t\"selp.u32 \$yi, \$cy$j, \$yi, \$mtp1;\\n\"\n";
+print "\t\"selp.u32 \$yi, \$cg$j, \$xr$j, \$mtp0;\\n\" \\\n";
+print "\t\"selp.u32 \$yi, \$cy$j, \$yi, \$mtp1;\\n\" \\\n";
 my $jm1 = $j-1;
 my $jm1 = $j-1;
 my $jm2 = $j-2;
 my $jm2 = $j-2;
 if ($j==1) {
 if ($j==1) {
-    print "\t\"setp.eq.u32 \$retaddr0,\$xr0,\$xr0;\\n\"\n";
+    print "\t\"setp.eq.u32 \$retaddr0,\$xr0,\$xr0;\\n\" \\\n";
 } else {
 } else {
-    print "\t\"setp.eq.u32 \$retaddr$jm1|\$retaddr$jm2,\$xr0,\$xr0;\\n\"\n";
+    print "\t\"setp.eq.u32 \$retaddr$jm1|\$retaddr$jm2,\$xr0,\$xr0;\\n\" \\\n";
 }
 }
-print "\t\"bra.uni innerloop;\\n\"\n";
-print "\t\"innerret$jm1:\\n\"\n";
+print "\t\"bra.uni innerloop;\\n\" \\\n";
+print "\t\"innerret$jm1:\\n\" \\\n";
 }
 }
 
 
 print <<'EOA';
 print <<'EOA';
-	"// Last iteration: store the output in x instead of z\n"
+	"// Last iteration: store the output in x instead of z\n" \
 EOA
 EOA
 
 
 # Pick the correct value of $yi
 # Pick the correct value of $yi
 my $yioff = ($WORDSm1)*4;
 my $yioff = ($WORDSm1)*4;
-print "\t\"selp.u32 \$yi, \$cg$WORDSm1, \$xr$WORDSm1, \$mtp0;\\n\"\n";
-print "\t\"selp.u32 \$yi, \$cy$WORDSm1, \$yi, \$mtp1;\\n\"\n";
+print "\t\"selp.u32 \$yi, \$cg$WORDSm1, \$xr$WORDSm1, \$mtp0;\\n\" \\\n";
+print "\t\"selp.u32 \$yi, \$cy$WORDSm1, \$yi, \$mtp1;\\n\" \\\n";
 
 
-print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\"\n";
-print "\t\"mad.wide.u32 \$cs, \$xr0, \$yi, \$ct;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr0, \$cs;\\n\"\n";
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\" \\\n";
+print "\t\"mad.wide.u32 \$cs, \$xr0, \$yi, \$ct;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr0, \$cs;\\n\" \\\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
 
 
 for($i=1; $i<$WORDS; ++$i) {
 for($i=1; $i<$WORDS; ++$i) {
     $xoff = $i*32*4;
     $xoff = $i*32*4;
-    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\"\n";
-    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-    print "\t\"mad.wide.u32 \$cs, \$xr$i, \$yi, \$cs;\\n\"\n";
-    print "\t\"cvt.u32.u64 \$zr$i, \$cs;\\n\"\n";
-    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
+    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\" \\\n";
+    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+    print "\t\"mad.wide.u32 \$cs, \$xr$i, \$yi, \$cs;\\n\" \\\n";
+    print "\t\"cvt.u32.u64 \$zr$i, \$cs;\\n\" \\\n";
+    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
 }
 }
-print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\"\n";
-print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\"\n";
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr$WORDSp1, \$cs;\\n\"\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\" \\\n";
+print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\" \\\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr$WORDSp1, \$cs;\\n\" \\\n";
 
 
-print "\t\"mul.lo.u32 \$m, \$zr0, \$crp;\\n\"\n";
-print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\"\n";
-print "\t\"mad.wide.u32 \$cs, \$m, \$crho0, \$ct;\\n\"\n";
+print "\t\"mul.lo.u32 \$m, \$zr0, \$crp;\\n\" \\\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\" \\\n";
+print "\t\"mad.wide.u32 \$cs, \$m, \$crho0, \$ct;\\n\" \\\n";
 
 
 for($i=1;$i<$WORDS;++$i) {
 for($i=1;$i<$WORDS;++$i) {
     my $im1 = $i-1;
     my $im1 = $i-1;
-    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\"\n";
-    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-    print "\t\"mad.wide.u32 \$cs, \$m, \$crho$i, \$cs;\\n\"\n";
-    print "\t\"cvt.u32.u64 \$xr$im1, \$cs;\\n\"\n";
+    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\" \\\n";
+    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+    print "\t\"mad.wide.u32 \$cs, \$m, \$crho$i, \$cs;\\n\" \\\n";
+    print "\t\"cvt.u32.u64 \$xr$im1, \$cs;\\n\" \\\n";
 }
 }
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\"\n";
-print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-print "\t\"cvt.u32.u64 \$xr$WORDSm1, \$cs;\\n\"\n";
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-print "\t\"cvt.u64.u32 \$ct, \$zr$WORDSp1;\\n\"\n";
-print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-print "\t\"cvt.u32.u64 \$xr$WORDS, \$cs;\\n\"\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\" \\\n";
+print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$xr$WORDSm1, \$cs;\\n\" \\\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr$WORDSp1;\\n\" \\\n";
+print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$xr$WORDS, \$cs;\\n\" \\\n";
 
 
 print <<'EOA';
 print <<'EOA';
-        );
+        ); \
 EOA
 EOA
 
 
 # If x >= c_rho, x <- x - c_rho
 # If x >= c_rho, x <- x - c_rho
 
 
-print "    asm(\n";
-print "\t\".reg.pred \$gtP,\$ltP;\\n\"\n";
-print "\t\"mov.u32 \$m, 0;\\n\"\n";
-print "\t\"setp.gt.u32 \$gtP, \$xr$WORDS, \$m;\\n\"\n";
-print "\t\"\@\$gtP bra \$comp_done;\\n\"\n";
+print "    asm volatile ( \\\n";
+print "\t\".reg.pred \$gtP,\$ltP;\\n\" \\\n";
+print "\t\"mov.u32 \$m, 0;\\n\" \\\n";
+print "\t\"setp.gt.u32 \$gtP, \$xr$WORDS, \$m;\\n\" \\\n";
+print "\t\"\@\$gtP bra \$comp_done;\\n\" \\\n";
 for ($i = $WORDS-1; $i >= 1; --$i) {
 for ($i = $WORDS-1; $i >= 1; --$i) {
-    print "\t\"setp.gt.u32 \$gtP, \$xr$i, \$crho$i;\\n\"\n";
-    print "\t\"\@\$gtP bra \$comp_done;\\n\"\n";
-    print "\t\"setp.lt.u32 \$ltP, \$xr$i, \$crho$i;\\n\"\n";
-    print "\t\"\@\$ltP bra \$comp_done;\\n\"\n";
+    print "\t\"setp.gt.u32 \$gtP, \$xr$i, \$crho$i;\\n\" \\\n";
+    print "\t\"\@\$gtP bra \$comp_done;\\n\" \\\n";
+    print "\t\"setp.lt.u32 \$ltP, \$xr$i, \$crho$i;\\n\" \\\n";
+    print "\t\"\@\$ltP bra \$comp_done;\\n\" \\\n";
 }
 }
-print "\t\"setp.ge.u32 \$gtP, \$xr0, \$crho0;\\n\"\n";
-print "\t\"\$comp_done:\\n\"\n";
+print "\t\"setp.ge.u32 \$gtP, \$xr0, \$crho0;\\n\" \\\n";
+print "\t\"\$comp_done:\\n\" \\\n";
 
 
 # Do the subtraction
 # Do the subtraction
-print "\t\"@\$gtP sub.cc.u32 \$xr0, \$xr0, \$crho0;\\n\"\n";
+print "\t\"@\$gtP sub.cc.u32 \$xr0, \$xr0, \$crho0;\\n\" \\\n";
 for ($i=1; $i<$WORDS; ++$i) {
 for ($i=1; $i<$WORDS; ++$i) {
-    print "\t\"@\$gtP subc.cc.u32 \$xr$i, \$xr$i, \$crho$i;\\n\"\n";
+    print "\t\"@\$gtP subc.cc.u32 \$xr$i, \$xr$i, \$crho$i;\\n\" \\\n";
 }
 }
-print "\t\"@\$gtP subc.u32 \$xr$WORDS, \$xr$WORDS, \$m;\\n\"\n";
+print "\t\"@\$gtP subc.u32 \$xr$WORDS, \$xr$WORDS, \$m;\\n\" \\\n";
 
 
-print "\t\"bra.uni mulmoddone;\\n\"\n";
+print "\t\"bra.uni mulmoddone;\\n\" \\\n";
 
 
-print "\t\"innerloop:\\n\"\n";
-print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\"\n";
-print "\t\"mad.wide.u32 \$cs, \$xr0, \$yi, \$ct;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr0, \$cs;\\n\"\n";
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
+print "\t\"innerloop:\\n\" \\\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\" \\\n";
+print "\t\"mad.wide.u32 \$cs, \$xr0, \$yi, \$ct;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr0, \$cs;\\n\" \\\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
 
 
 my $i;
 my $i;
 for($i=1; $i<$WORDS; ++$i) {
 for($i=1; $i<$WORDS; ++$i) {
-    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\"\n";
-    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-    print "\t\"mad.wide.u32 \$cs, \$xr$i, \$yi, \$cs;\\n\"\n";
-    print "\t\"cvt.u32.u64 \$zr$i, \$cs;\\n\"\n";
-    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
+    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\" \\\n";
+    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+    print "\t\"mad.wide.u32 \$cs, \$xr$i, \$yi, \$cs;\\n\" \\\n";
+    print "\t\"cvt.u32.u64 \$zr$i, \$cs;\\n\" \\\n";
+    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
 }
 }
-print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\"\n";
-print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\"\n";
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr$WORDSp1, \$cs;\\n\"\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\" \\\n";
+print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\" \\\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr$WORDSp1, \$cs;\\n\" \\\n";
 
 
-print "\t\"mul.lo.u32 \$m, \$zr0, \$crp;\\n\"\n";
-print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\"\n";
-print "\t\"mad.wide.u32 \$cs, \$m, \$crho0, \$ct;\\n\"\n";
+print "\t\"mul.lo.u32 \$m, \$zr0, \$crp;\\n\" \\\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr0;\\n\" \\\n";
+print "\t\"mad.wide.u32 \$cs, \$m, \$crho0, \$ct;\\n\" \\\n";
 
 
 for($i=1;$i<$WORDS;++$i) {
 for($i=1;$i<$WORDS;++$i) {
     my $im1 = ($i-1);
     my $im1 = ($i-1);
-    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\"\n";
-    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-    print "\t\"mad.wide.u32 \$cs, \$m, \$crho$i, \$cs;\\n\"\n";
-    print "\t\"cvt.u32.u64 \$zr$im1, \$cs;\\n\"\n";
+    print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+    print "\t\"cvt.u64.u32 \$ct, \$zr$i;\\n\" \\\n";
+    print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+    print "\t\"mad.wide.u32 \$cs, \$m, \$crho$i, \$cs;\\n\" \\\n";
+    print "\t\"cvt.u32.u64 \$zr$im1, \$cs;\\n\" \\\n";
 }
 }
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\"\n";
-print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr$WORDSm1, \$cs;\\n\"\n";
-print "\t\"shr.u64 \$cs, \$cs, 32;\\n\"\n";
-print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\"\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+print "\t\"cvt.u64.u32 \$ct, \$zr$WORDS;\\n\" \\\n";
+print "\t\"add.u64 \$cs, \$cs, \$ct;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr$WORDSm1, \$cs;\\n\" \\\n";
+print "\t\"shr.u64 \$cs, \$cs, 32;\\n\" \\\n";
+print "\t\"cvt.u32.u64 \$zr$WORDS, \$cs;\\n\" \\\n";
 
 
 for ($i=0;$i<$WORDS-2;++$i) {
 for ($i=0;$i<$WORDS-2;++$i) {
-    print "\t\"\@\$retaddr$i bra.uni innerret$i;\\n\"\n";
+    print "\t\"\@\$retaddr$i bra.uni innerret$i;\\n\" \\\n";
 }
 }
-print "\t\"mulmoddone:\\n\"\n";
+print "\t\"mulmoddone:\\n\" \\\n";
 
 
-print "    );\n";
-print "}\n";
+print "    )\n";
 
 
 print <<'EOA';
 print <<'EOA';
 
 
-__device__ inline void write_dp(unsigned int *buf, unsigned int a_0,
-    unsigned int a_1, unsigned int a_2, unsigned int b_0, unsigned int b_1,
-    unsigned int b_2)
-{
-    unsigned short blockid = blockIdx.x + gridDim.x*blockIdx.y;
-    unsigned short threadid = threadIdx.x + blockDim.x*threadIdx.y + blockDim.x*blockDim.y*threadIdx.z;
-    buf[0] = (((unsigned int)blockid) << 16) + threadid;
-    asm(
+#define CIOS_WRITE_DP(buf, a_0, a_1, a_2, b_0, b_1, b_2) \
+do { \
+    unsigned short blockid = blockIdx.x + gridDim.x*blockIdx.y; \
+    unsigned short threadid = threadIdx.x + blockDim.x*threadIdx.y + blockDim.x*blockDim.y*threadIdx.z; \
+    buf[0] = (((unsigned int)blockid) << 16) + threadid; \
+    asm volatile ( \
 EOA
 EOA
 for($i=0;$i<$WORDS;++$i) {
 for($i=0;$i<$WORDS;++$i) {
     my $off = 4*($i+1);
     my $off = 4*($i+1);
-    print "\t\"st.global.u32 [%0+$off], \$xr$i;\\n\"\n";
+    print "\t\"st.u32 [%0+$off], \$xr$i;\\n\" \\\n";
 }
 }
 print <<'EOA';
 print <<'EOA';
-    : : "l" (buf));
-    buf[WORDS+1] = a_0;
-    buf[WORDS+2] = a_1;
-    buf[WORDS+3] = a_2;
-    buf[WORDS+4] = b_0;
-    buf[WORDS+5] = b_1;
-    buf[WORDS+6] = b_2;
-}
+    : : "l" (buf)); \
+    buf[WORDS+1] = a_0; \
+    buf[WORDS+2] = a_1; \
+    buf[WORDS+3] = a_2; \
+    buf[WORDS+4] = b_0; \
+    buf[WORDS+5] = b_1; \
+    buf[WORDS+6] = b_2; \
+} while(0)
 EOA
 EOA

+ 14 - 10
parrhoasm.cu

@@ -42,6 +42,11 @@
 #define SIZE_Y WORDS
 #define SIZE_Y WORDS
 #define SIZE_X (WORDS + 1)
 #define SIZE_X (WORDS + 1)
 
 
+__device__ __constant__ unsigned int c_rho[WORDS + 1], c_r_inv[WORDS + 1], c_rho_prime;
+__device__ __constant__ unsigned int c_y[SIZE_Y], c_g[SIZE_G];
+
+#include "cios.asm"
+
 #include "dpstream.cu"
 #include "dpstream.cu"
 
 
 // #define X(idx) x[idx<<5]
 // #define X(idx) x[idx<<5]
@@ -85,9 +90,6 @@ typedef struct
 } GlobalThreadState;
 } GlobalThreadState;
 
 
 
 
-__device__ __constant__ unsigned int c_rho[WORDS + 1], c_r_inv[WORDS + 1], c_rho_prime;
-__device__ __constant__ unsigned int c_y[SIZE_Y], c_g[SIZE_G];
-
 /*
 /*
 __device__ unsigned int getgy(int i)
 __device__ unsigned int getgy(int i)
 {
 {
@@ -95,8 +97,6 @@ __device__ unsigned int getgy(int i)
 }
 }
 */
 */
 
 
-#include "cios.asm"
-
 #if 0
 #if 0
 __device__ void _sub(unsigned int *x)
 __device__ void _sub(unsigned int *x)
 // x <- x - y
 // x <- x - y
@@ -191,6 +191,8 @@ __global__ void cudaMulmod(GlobalThreadState *global_ts,
 	unsigned int order_0, unsigned int order_1, unsigned int order_2)
 	unsigned int order_0, unsigned int order_1, unsigned int order_2)
 // x <- x * y mod rho
 // x <- x * y mod rho
 {
 {
+    CIOS_REG_DECLARE;
+
     // extern __shared__ unsigned int sharedmem[];
     // extern __shared__ unsigned int sharedmem[];
     register int i;
     register int i;
     register int tid = threadIdx.x + threadDimx * threadIdx.y;
     register int tid = threadIdx.x + threadDimx * threadIdx.y;
@@ -205,7 +207,7 @@ __global__ void cudaMulmod(GlobalThreadState *global_ts,
     unsigned int xlow;
     unsigned int xlow;
 
 
     // cuPrintf("d_z = %08X%08X%08X\n", global_x_base[2], global_x_base[1], global_x_base[0]);
     // cuPrintf("d_z = %08X%08X%08X\n", global_x_base[2], global_x_base[1], global_x_base[0]);
-    loadx(global_x_base);
+    CIOS_LOADX(global_x_base);
     a_2 = global_a_base[2];
     a_2 = global_a_base[2];
     a_1 = global_a_base[1];
     a_1 = global_a_base[1];
     a_0 = global_a_base[0];
     a_0 = global_a_base[0];
@@ -267,7 +269,7 @@ __global__ void cudaMulmod(GlobalThreadState *global_ts,
 	    asm("subc.u32 %0, %1, %2;" : "=r"(b_2) : "r"(b_2), "r"(order_2));
 	    asm("subc.u32 %0, %1, %2;" : "=r"(b_2) : "r"(b_2), "r"(order_2));
 	}
 	}
 		
 		
-        modmul(multtype);
+        CIOS_MODMUL(multtype);
         //memcpy(ts[tid].x, ts[tid].z, (WORDS + 1) * sizeof(unsigned int));
         //memcpy(ts[tid].x, ts[tid].z, (WORDS + 1) * sizeof(unsigned int));
 	/*
 	/*
         if (_gt(shared_x_base)) {
         if (_gt(shared_x_base)) {
@@ -281,10 +283,13 @@ __global__ void cudaMulmod(GlobalThreadState *global_ts,
 	// Check for a distinguished point
 	// Check for a distinguished point
 	asm("mov.u32 %0, $xr0;" : "=r" (xlow));
 	asm("mov.u32 %0, $xr0;" : "=r" (xlow));
 	if ((xlow & 0x000003ff) == 0 || !(order_2|order_1) && order_0 < (1<<20)) {
 	if ((xlow & 0x000003ff) == 0 || !(order_2|order_1) && order_0 < (1<<20)) {
-	    DPstreamWrite(a_0,a_1,a_2,b_0,b_1,b_2);
+	    unsigned int *ourbuffer = DPstreamWrite(a_0,a_1,a_2,b_0,b_1,b_2);
+	    if (ourbuffer) {
+		CIOS_WRITE_DP(ourbuffer, a_0, a_1, a_2, b_0, b_1, b_2);
+	    }
 	}
 	}
     }
     }
-    savex(global_x_base);
+    CIOS_SAVEX(global_x_base);
     global_a_base[0] = a_0;
     global_a_base[0] = a_0;
     global_a_base[1] = a_1;
     global_a_base[1] = a_1;
     global_a_base[2] = a_2;
     global_a_base[2] = a_2;
@@ -296,7 +301,6 @@ __global__ void cudaMulmod(GlobalThreadState *global_ts,
     // cuPrintf("d_B = %08X\n", (unsigned int)b);
     // cuPrintf("d_B = %08X\n", (unsigned int)b);
     // cuPrintf("d_a = %08X%08X\n", global_a_base[1], global_a_base[0]);
     // cuPrintf("d_a = %08X%08X\n", global_a_base[1], global_a_base[0]);
     // cuPrintf("d_b = %08X%08X\n", global_b_base[1], global_b_base[0]);
     // cuPrintf("d_b = %08X%08X\n", global_b_base[1], global_b_base[0]);
-    if (!(order_0|order_1|order_2)) evilhack();
 }
 }
 
 
 int nthreads = 25600;
 int nthreads = 25600;