diff --git a/libtcc.c b/libtcc.c
index f184502b..b824c184 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -752,6 +752,7 @@ LIBTCCAPI TCCState *tcc_new(void)
     s->alacarte_link = 1;
     s->nocommon = 1;
     s->warn_implicit_function_declaration = 1;
+    s->ms_bitfields = 0;
 
 #ifdef CHAR_IS_UNSIGNED
     s->char_is_unsigned = 1;
@@ -1508,6 +1509,7 @@ enum {
     TCC_OPTION_Wl,
     TCC_OPTION_W,
     TCC_OPTION_O,
+    TCC_OPTION_mms_bitfields,
     TCC_OPTION_m,
     TCC_OPTION_f,
     TCC_OPTION_isystem,
@@ -1571,6 +1573,7 @@ static const TCCOption tcc_options[] = {
     { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "mms-bitfields", TCC_OPTION_mms_bitfields, 0}, /* must go before option 'm' */
     { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
     { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
@@ -1854,6 +1857,9 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
             if (x > 0)
                 tcc_define_symbol(s, "__OPTIMIZE__", NULL);
             break;
+        case TCC_OPTION_mms_bitfields:
+            s->ms_bitfields = 1;
+            break;
         case TCC_OPTION_traditional:
         case TCC_OPTION_pedantic:
         case TCC_OPTION_pipe:
diff --git a/tcc-doc.texi b/tcc-doc.texi
index 5aab13cc..9f136ed6 100644
--- a/tcc-doc.texi
+++ b/tcc-doc.texi
@@ -176,6 +176,10 @@ In a script, it gives the following header:
 #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
 @end example
 
+@item -mms-bitfields
+Use an algorithm for bitfield alignment consistent with MSVC. Default is
+gcc's algorithm.
+
 @item -mfloat-abi (ARM only)
 Select the float ABI. Possible values: @code{softfp} and @code{hard}
 
diff --git a/tcc.c b/tcc.c
index 28f3ae94..fbfbffa8 100644
--- a/tcc.c
+++ b/tcc.c
@@ -97,6 +97,7 @@ static void help(void)
            "  -o outfile  set output filename\n"
            "  -run        run compiled source\n"
            "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
+           "  -mms-bitfields  use bitfield alignment consistent with MSVC\n"
            "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
            "  -w          disable all warnings\n"
            "  -v          show version\n"
diff --git a/tcc.h b/tcc.h
index 180838dd..cbdebd37 100644
--- a/tcc.h
+++ b/tcc.h
@@ -605,6 +605,7 @@ struct TCCState {
     int old_struct_init_code;	/* use old algorithm to init array in struct when there is no '{' used.
 				   Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
     int dollars_in_identifiers;	/* allows '$' char in indentifiers */
+    int ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
 
     /* warning switches */
     int warn_write_strings;
diff --git a/tccgen.c b/tccgen.c
index ba1757e1..d0640245 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3154,7 +3154,7 @@ static void parse_attribute(AttributeDef *ad)
 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
 static void struct_decl(CType *type, AttributeDef *ad, int u)
 {
-    int a, v, size, align, maxalign, c, offset, flexible;
+    int a, v, size, align, maxalign, c, offset, flexible, extra_bytes;
     int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
     Sym *s, *ss, *ass, **ps;
     AttributeDef ad1;
@@ -3235,6 +3235,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
             while (tok != '}') {
                 parse_btype(&btype, &ad1);
                 while (1) {
+                extra_bytes = 0;
 		    if (flexible)
 		        tcc_error("flexible array member '%s' not at the end of struct",
                               get_tok_str(v, NULL));
@@ -3310,9 +3311,9 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
                             /* zero size: means to pad */
                             bit_pos = 0;
                         } else {
-                            /* we do not have enough room ?
-                               did the type change?
-                               is it a union? */
+                            /* if type change, union, or will overrun
+                             * allignment slot, start at a newly
+                             * alligned slot */
                             if ((bit_pos + bit_size) > bsize ||
                                 bt != prevbt || a == TOK_UNION)
                                 bit_pos = 0;
@@ -3322,15 +3323,30 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
                                 (bit_pos << VT_STRUCT_SHIFT) |
                                 (bit_size << (VT_STRUCT_SHIFT + 6));
                             bit_pos += bit_size;
+                            /* without ms-bitfields, allocate the
+                             * minimum number of bytes necessary,
+                             * adding single bytes as needed */
+                            if (!tcc_state->ms_bitfields) {
+                                if (lbit_pos == 0)
+                                    /* minimum bytes for new bitfield */
+                                    size = (bit_size + 7) / 8;
+                                else {
+                                    /* enough spare bits already allocated? */
+                                    bit_size = (lbit_pos - 1) % 8 + 1 + bit_size;
+                                    if (bit_size > 8) /* doesn't fit */
+                                        extra_bytes = (bit_size - 1) / 8;
+                                }
+                            }
                         }
                         prevbt = bt;
                     } else {
                         bit_pos = 0;
                     }
                     if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
-                        /* add new memory data only if starting
-                           bit field */
-                        if (lbit_pos == 0) {
+                        /* add new memory data only if starting bit
+                           field or adding bytes to existing bit field */
+                        if (extra_bytes) c += extra_bytes;
+                        else if (lbit_pos == 0) {
                             if (a == TOK_STRUCT) {
                                 c = (c + align - 1) & -align;
                                 offset = c;
diff --git a/tests/tcctest.c b/tests/tcctest.c
index 5851fb4e..b0fe8f38 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -1634,6 +1634,15 @@ void bitfield_test(void)
     st2.f3 = a;
     st2.f2++;
     printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
+    struct sbf3 {
+        int f1 : 7;
+        int f2 : 1;
+        char f3;
+        int f4 : 8;
+        int f5 : 1;
+        int f6 : 16;
+    } st3;
+    printf("sizeof(st3) = %d\n", sizeof(st3));
 }
 
 #ifdef __x86_64__