__constant_memcpy_fromfs function makes angry compiler

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

__constant_memcpy_fromfs function makes angry compiler

Post by piranha »

I used (borrowed) some code from Linux-1.0, segment.h:

Code: Select all

static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
{
	switch (n) {
		case 0:
			return;
		case 1:
			*(char *)to = get_user_byte((const char *) from);
			return;
		case 2:
			*(short *)to = get_user_word((const short *) from);
			return;
		case 3:
			*(short *) to = get_user_word((const short *) from);
			*(char *) to = get_user_byte(2+(const char *) from);
			return;
		case 4:
			*(int *) to = get_user_long((const int *) from);
			return;
	}
#define COMMON(x) \
	__asm__("cld\n\t" \
	"rep ; fs ; movsl\n\t" \
	x \
	: /* no outputs*/  \
	:"c" (n/4),"D" ((long) to),"S" ((long) from) \
	:"cx","di","si","memory")

	switch (n % 4) {
		case 0:
			COMMON("");
			return;
		case 1:
			COMMON("fs ; movsb");
			return;
		case 2:
			COMMON("fs ; movsw");
			return;
		case 3:
			COMMON("fs ; movsw\n\tfs ; movsb");
			return;
	}
#undef COMMON
}
However, when I compile, I get:
include/segment.h: In function ‘__constant_memcpy_fromfs’:
include/segment.h:188: error: can't find a register in class ‘CREG’ while reloading ‘asm’
include/segment.h:191: error: can't find a register in class ‘CREG’ while reloading ‘asm’
include/segment.h:194: error: can't find a register in class ‘CREG’ while reloading ‘asm’
include/segment.h:197: error: can't find a register in class ‘CREG’ while reloading ‘asm’
include/segment.h:188: error: ‘asm’ operand has impossible constraints
include/segment.h:191: error: ‘asm’ operand has impossible constraints
include/segment.h:194: error: ‘asm’ operand has impossible constraints
include/segment.h:197: error: ‘asm’ operand has impossible constraints
Any idea why? I'm not that great with the asm, or gcc asm and such...
-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
CodeCat
Member
Member
Posts: 158
Joined: Tue Sep 23, 2008 1:45 pm
Location: Eindhoven, Netherlands

Re: __constant_memcpy_fromfs function makes angry compiler

Post by CodeCat »

I just figured this one out today coincidentally.

The problem is that you're specifying "cx","di","si" as clobbered registers, but gcc assumes that the input registers are left untouched. So it gets stuck because it can't both assume a register is untouched and clobbered. The solution is to use a dummy output, like this:

Code: Select all

short d0, d1, d2;
   __asm__("cld\n\t" \
   "rep ; fs ; movsl\n\t" \
   x \
   :"=&c" (d0), "=&D" (d1), "=&S" (d2)  \
   :"0" (n/4),"1" ((long) to),"2" ((long) from) \
   :"memory")
Also don't forget to add "cc" to the clobber list, because you changed the flags (cld).
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Re: __constant_memcpy_fromfs function makes angry compiler

Post by piranha »

Thanks, that wokeded.

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
Post Reply